Best practices for cross platform Meteor apps with a single codebase?

React + ReactRouter + ReactMeteorData + Material UI

4 Likes

React seems to be the way to go in general for Meteor, let’s see if this combination is suited for single codebase apps. Will look into it. Thank you.

We have a single code base app that runs on web, Android and iOS. We currently run react v16.8.6, react-router v3.2.1, material-ui/core v4.0.0-alpha.5 and our own customized version of the functions composeWithTracker and compose derived from react-composer v2.0. As you are starting a new app probably best to take @awatson1978 recommendation to use react-meteor-data.

I’d highly recommend you also consider using simple schema with uniforms for form generation as it is really easy and customizable. There is a uniforms Material-UI package as well.

We also make judicious use of Meteor.isCordova with dynamic imports to load code that is only needed on mobile or not. For layout changes on mobile versus web, and for different mobile screen sizes, we make use of Material UI’s breakpoints, dynamic styling, and their withWidth() component, but you can do the same with their media queries.

All in all, the latest version of Material UI is pretty good for mobile apps if you are fine with the styling on iOS. We are as our app is an enterprise app so our user’s don’t expect everything to work exactly like a full Apple iOS app. Good luck!

2 Likes

If you use Material UI here are some examples of how we do global theme changes based on screen size or if running in Cordova.

See the Material UI themes documentation. In your custom theme you can not only set custom colors such as

export const colorPrimary = '#cb4545';

but also layout values you can import and use to dynamically change the layout at run-time.

export const drawerWidth = 280;
export const miniDrawerWidth = 64;
export const appBarHeight = Meteor.isCordova ? 56 : 64;

Here are some example of using overrides and props to change layout of components globally and dynamically. For instance, we change font size for inputs to 13px on web as this looks better and is more dense, but for mobile set back to default of 16px.

// Customize my theme definition
const myTheme = createMuiTheme({
  palette: {
    primary: {
      main: colorPrimary
    }
  },
  props: {
    MuiTextField: {
      fullWidth: true,
      margin: 'dense',
      variant: 'outlined'
    }
  },
  overrides: {
    MuiFormLabel: {
      root: {
        fontSize: 13 // Default 16
      }
    },
    MuiInput: {
      input: {
        fontSize: 13 // Default 16
      }
    },
    MuiOutlinedInput: {
      input: {
        fontSize: 13 // Default 16
      }
    },
    MuiToolbar: {
      regular: {
        minHeight: appBarHeight // 56, 64
      }
    }
  }
});

// Make fonts larger on smaller mobile screens
myTheme.overrides.MuiFormLabel.root[myTheme.breakpoints.down('sm')] = {fontSize: 16};
myTheme.overrides.MuiInput.input[myTheme.breakpoints.down('sm')] = {fontSize: 16};
myTheme.overrides.MuiOutlinedInput.input[myTheme.breakpoints.down('sm')] = {fontSize: 16};

export default myTheme;

Hope this helps.

2 Likes

I run www.virtualinout.com from a single codebase with Web, iOS and Android apps, using Cordova and Material Design Lite (using zodiase:mdl but if I was to start over I would probably use Material Components).

Every feature and UI is written once and runs happily on all platforms. Material Design adapts nicely and seems to work well on all devices - you just need to test the layout on a variety of screen sizes and play with the grid or CSS media queries to make things work.

For the UI framework I cannot recommend Vue.js highly enough. My app started with Blaze, then I begrudgingly converted to React to achieve SSR, but I never liked the verbosity of React. Recently I converted the whole thing to Vue.js because (in my opinion) it it is much easier & faster to work with. Two-way binding (if you want it) just works, computed properties make re-rendering more efficient, and I personally find the template easier to work with in HTML rather than JSX.

I’ve posted in the Vue.js forums about the performance results of the switch from React to Vue.

Good luck!

1 Like

My favourite stack atm is Meteor/Apollo backend with react-native codebase for web, ios and android powered by react-native web.

So you have two native apps and a very performant webapp with one codebase. In future I will release a ui kit for react-native build with web in mind.

3 Likes

progressive web apps
They are recognized by android and iOS as apps
both will allow you to put a shortcut on their apps menu
no app store needed
and in the case of android, it will even show a splash screen that you can configure with a manifest
and pass a variable so you can show some extra stuff in your “app mode”
I don’t use that but there you have more options
The only thing you need to make for this, is a very responsible UI
bootstrap is recomended

Here’s one of my apps that work this way (desktop, webapk -natively added from browser-, and iOS browser -that can also add it as a webapk-), all of them from the same single source, changing behavior depending on the screen size




about the manifest

1 Like

I really want to try Apollo, I’ve been reading and it solves many things like going from mongo to MySQL and such, an surely way more things that I’m yet not aware of

I’m happy with: Meteor,Vue and vuetify (material design with UI cpmponent) before that I used meteor blaze, MDL

Completely agree and they are fantastic. However, in my experience most users don’t understand this, and they want an app they can install from the App Store. I started off with progressive web apps but got so tired of having to explain that the web app has exactly the same functionality in the end I gave up and compiled with Cordova. Meteor made this so easy.

Also, from a sales perspective, having a presence in the app stores is another route to market, plus having prominent app store buttons on the web sales pages in beneficial.

3 Likes

@wildhart I’m planning on doing the same. Any pro tips? Did you simply follow the Meteor Guide?

The meteor mobile guide is comprehensive and fantastic - everything you need to get setup, compile and submitted to the app stores is there.

I guess a good tip is to be very selective which Cordova plug-ins you use - if any. There are many plug-ins out there, including forks of forks of forks, so finding one which is up-to-date, still maintained and compatible with your version of Cordova can be a challenge sometimes!

2 Likes

yea, I can see why it can get annoying.
I’ve read that a progressive web app can actually make it to the android store
they requests some things for that, but it is possible
but yea, iOS gives PWA the big NO, so without making it an app, you lose a huge market right there.
I’ve had some problems with Cordova in the past, but when it works, it works like a charm.
Got no problems using PWA so far, so I hope it becomes defacto soon enough.

Single code base for me means missing on a huge opportunity to have them completely separated.

1 Like

Thank you for all the input so far.
I will look into “progressive web apps” but I think the app store presence is a big point like @wildhart mentioned.
And many thanks to @skirunman who very detailed described their single codebase react stack, I will definitely look into that.

And as @paulishca said: “Single code base for me means missing on a huge opportunity to have them completely separated.” that is true, but after all the goal is a KISS principle for a small app that is easily maintained with as little effort as possible over years. That is why a single codebase is so important for me.

3 Likes

For big apps, I might agree, but for small apps mantained by a small team/single person, having more things to worry about means more man-hours and more headaches, and 2 possible sources of failures, and it makes your product more expensive in the end, a single source reduces costs, resource usages, and man-hours on small apps (and keeping the same look and feel everywhere).

@apalgen good luck!

@felbrasil I (almost) agree. But 2 possible sources of failure is a benefit not only a possible problem because at times you notice a bug in web and … your mobile app is still doing fine because you didn’t push that to mobile. More things to worry about can also mean that you enjoy the leisure of worrying one by one. You are 95% right if the app is small, prototype and it is supposed to stay small for its entire life. I feel that otherwise, separation is an opportunity.

1 Like

I am trying to achieve the same thing with the following stack:

But I have not implemented a real-world app yet nor tried mobile deployment so I cannot yet confirm that it is indeed a good choice in practice.

Good luck and keep us posted on your choice and progress!

Hey there, can you share more resources on vue and meteor? How did you handle accounts? Any templates to learn from?
Single code case even with vue as front end? I thought converting your meteor app to ios or android was only possible if you used blaze as frontend. How did you achieve that with vue as frontend?

Hi @nosizejosh,

For accounts, I just use the standard meteor accounts system with my own Vue templates for creating users, setting/resetting passwords.

I use vuetify for Material Design which scales well from desktop to mobile, and looks fairly close to native android.

Cordova doesn’t care what your front end library is, it just renders your page in an embedded browser. It can use blaze, vue, react, svelte, whatever you want. Once you’ve got the webpage working, add cordova and compile.

There is a new official Vue tutorial for Meteor which includes adding accounts, so give that a go. Once you’ve got it working follow the mobile guide to add Cordova.

1 Like