[Cordova/PWA] today's thoughts

I’d like to share some thoughts about developing mobile applications, including with Cordova or PWA technology.
I believe that the functionality provided by PWA development today is comprehensive enough to avoid having to develop for Cordova as well.
I believe that all the parts most closely related to mobile hardware are possible using HTML/JS.
I’d appreciate some thoughts on this; I probably haven’t thought of everything.

I’d be interested in hearing more about this. What are a couple of examples of native UX features have previously been hard to reproduce on a PWA, that can now be matched via HTML/JS?

I think this has all the APIs: https://whatpwacando.today/

1 Like

Great place to develop new ideas !

I’m cooking something to be able to meteor create myapp --pwa :+1:

The idea: a Meteor scaffold flag that ships an app already passing Lighthouse PWA, with the modern Web APIs wired up out of the box — so we stop sending people to “go install jam:offline + pwa-kit + figure out a Workbox setup”.

Here’s a peek at what would land in the generated app:

Installable by default

  • public/manifest.webmanifest complete (icons 192/512/maskable, theme color, display=standalone, shortcuts, id)
  • public/sw.js registered on Meteor.startup
  • beforeinstallprompt captured + reactive install button (with 7-day dismissal cooldown)
  • Live display-mode badge (standalone / minimal-ui / fullscreen / window-controls-overlay / iOS standalone)

Offline-first with Workbox

  • App shell precache, StaleWhileRevalidate for the bundle, CacheFirst for images/fonts
  • NavigationRoute with a /offline.html fallback
  • /sockjs/ and /websocket correctly skipped — DDP never gets cached
  • Same-origin guards so chrome-extension:// requests don’t crash Cache.put
  • Reactive isOnline indicator + “new version ready, reload” banner driven by SW lifecycle

Storage stack

  • IndexedDB mirror of any reactive cursor: mirrorCollectionToIdb(cursor, store)
  • hydrateCollection(coll, store) at boot → Minimongo gets populated before DDP returns, so the UI renders instantly even offline
  • StorageManager helpers: live quota usage, Request persistent storage button
  • Web Locks coordination between tabs (withLock('sync', cb))
  • BroadcastChannel pwa-demo so two tabs talk without a server round-trip

Web Push out of the box

  • VAPID keys generated and wired into Meteor.settings
  • Server push.subscribe / push.unsubscribe / push.send methods, with auto-pruning of 410 Gone endpoints
  • SW handles push / notificationclick / pushsubscriptionchange
  • One-click “Enable notifications” → real OS notification

Meteor-specific quality of life

  • visibilitychangeMeteor.reconnect() if DDP is stale (Chrome aggressively throttles backgrounded standalone PWAs and the WebSocket can drop without surfacing fresh data until you reload — fixed)
  • DDP status badge in the UI

What’s next on the bench

  • Passkeys / WebAuthn login handler (Accounts.registerLoginHandler('webauthn', ...))
  • View Transitions + Window Controls Overlay for the standalone titlebar
  • Background Sync / Background Fetch for offline writes
  • Generic Sensors, Web Speech, MediaRecorder — to start the Cordova-replacement story we’ve been discussing in #64577

The whole thing is being built and validated as a standalone reference app (Meteor 3.4 + Blaze, no jam:offline, pure web standards). Once the bench is green, the goal is to fold it into a meteor create --pwa flag and/or a dupontbertrand:pwa Atmosphere package :partying_face: :dancing_men:

3 Likes

Very interesting.
Just a fast curiosity: I’m not sure if you want to include jam:offline as offline management or not.

@nachocodoner Isn’t that something Nacho already tackled??

Yes, I created a new example, notes-offline, as part of the rework of all meteor/examples.

We have announced them in the forum post: Revitalized Meteor Examples: Showcasing what Meteor can do today.

That example is a PWA and uses Meteor, Rspack, React, Mantine UI, jam:offline, jam:method, jam:pub-sub, jam:soft-delete, Zod, Workbox, LinguiJS, Mocha, ESLint, Prettier, and Playwright.
Live at: https://notes-offline.sandbox.galaxycloud.app

To check out the example app:

meteor create my-notes-offline --release 3.4.1 --example notes-offline

It provides another use case for Meteor nowadays, showcasing Rspack and Workbox integration as a way to automate SW generation. It also highlights community packages that have put a lot of effort into integrating great capabilities that work properly with native Meteor core concepts, like the jam:* family with jam:offline. It also includes extras as i18n integration wiht LinguiJs.

Native is really interesting area, and PWA/offline support is part of it. One of Meteor’s strengths from the early conception has been letting you focus on one stack, the web, to deploy apps across multiple platforms. This saves resources and lets you specialize in the web to unify the experience, not only for users, but also for you as a dev: unified dev environment, testing, benchmarking, JS/TS, etc.

We are heading into a time where Meteor can really focus more effort in this area, so all experimentation and shared knowledge is appreciated. Working on notes-offline was basically for that. Any other example using similar APIs is great to see, so everyone can be aware of the capabilities.

We’re talking about Cordova here, but CapacitorJS takes a different approach: its plugin API is designed to work uniformly across three targets, iOS, Android, and the web, calling native components on mobile and falling back to standard browser APIs when running in a web context. Working with CapacitorJS has effectively given us a single, consistent API to drive flows across devices, and its upcoming integration into Meteor is going to put that strength on full display.

1 Like

About jam:offline, I asked about this because I looked into adopting it in my apps, but I found a problem.
In my apps, I often use the Decimal128 field type to work around the issue of numbers and precision in JS.
Unfortunately, jam:offline doesn’t support this data type and doesn’t allow me to implement it.
I also open an issue, I hope it will be evaluated :crossed_fingers:

1 Like

Yes, notes-offline is definitely a very useful example, and I’m not trying to dismiss it, but I don’t think it solves exactly the same problem :thinking:

From what I understand, notes-offline is a full reference application. It shows that we can build a modern offline/PWA app with Meteor, Rspack, React, Mantine UI, jam:offline, jam:method, jam:pub-sub, jam:soft-delete, etc.

That’s great as an example, but my point is more about the baseline Meteor experience

And I guess this comes from the same recurring debate you’ve probably seen in several of my posts :smile:: I keep pushing for Meteor to become a bit more opinionated again

An example app is great. But for a newcomer, it can still feel like: “Here is an app with a lot of packages, good luck understanding which part is Meteor, which part is React/Mantine, which part is jam:*, which part is Workbox, and how to reproduce this cleanly in your own app.”

What I would like Meteor to answer more directly is:

How do I build a PWA with Meteor?

Without having to jump between multiple packages, multiple docs, an example app, Workbox docs, community conventions, and then figure out the recommended setup by myself.

That’s why I’m thinking more about something closer to an official PWA target/scaffold, for example:

meteor create my-app --pwa

or maybe:

meteor add pwa

The goal would be to have a minimal official Meteor PWA foundation that works out of the box:

  • web app manifest
  • service worker setup
  • offline fallback
  • safe default caching strategy
  • DDP-aware cache rules
  • installable app behavior
  • Lighthouse PWA checks passing by default
  • maybe optional helpers for push notifications / IndexedDB later

For me, this should be part of the official Meteor developer experience, either directly in core, as an official package, or as an official skeleton :man_shrugging:

That would also mean one place for the docs, one place for the recommended defaults, one place for maintenance, and one clear answer for newcomers.

notes-offline answers: “Can we build a serious offline-first app with Meteor today?”

The thing I’m talking about is more: “Can Meteor officially make PWA support a first-class starting point?”

3 Likes

I agree with what you say.

We should encourage more skeleton-like useful setups. A skeleton should worry less about app features and focus more on project configuration. An example is more about visuals and the experience of a real app, mixing many concepts to provide a full app experience. I would like to have more skeletons in core as well, especially as we solve more problems there.

For PWA, after the Rspack and Workbox experimentation, I’d say there is an approach that can be encapsulated in its own direct skeleton. But I also know that everything related to native experiences, including offline and PWA, is something we will build over the next months and take more opinionated directions on as we go. So we will definitely have more mature setups that feel natural in Meteor over time.

Let me know when you have your PWA skeleton proposals so we can review it. :rocket:

1 Like