Hello, community!
CapacitorJS will join a future Meteor minor release, with the exact version still to be determined. After several months of work, the integration is functional and ready for pre-beta experimentation.
Current Capacitor integration is experimental checkout work, not a published Meteor package. Commands, native project setup, plugin and runtime interfaces, and Hot Code Push behavior can change. Use core PR manual setup or examples PR Hands-on walkthrough for current testing steps.
We prepared the Meteor core integration and three native examples covering Capacitor plugins, native-only features, Meteor data flows, Hot Code Push, and Android and iOS workflows.
This is the integration we plan to take through an official Meteor beta and release, not a separate proof of concept. We are sharing it now so community can try this long-requested feature and help shape it.
Why CapacitorJS
CapacitorJS updates one of Meteor’s most distinctive features: writing an application mainly in JavaScript and deploying it across the browser, Android, and iOS. Teams can reuse application logic, data flows, and product knowledge instead of maintaining disconnected stacks. Progressive Web Apps are valuable, but they do not replace app-store distribution for every product or audience. Making native delivery easier remains a clear reason for web developers to choose Meteor.
A modern successor, not a different application model. CapacitorJS and Cordova both use a WebView. Their main differences are features, maintenance, developer control, and access to the modern native ecosystem.
A healthier plugin ecosystem. CapacitorJS provides an actively maintained core and plugin ecosystem. Cordova continues to receive updates and remains enough for many applications, but important plugins may become abandoned, deprecated, or slow to support new native APIs. RevenueCat, for example, deprecated its Cordova plugin in favor of CapacitorJS. Cases like this will become more common as native platforms evolve. Capacitor plugins use npm, commonly provide typed Promise-based APIs and browser fallbacks, and follow current native SDKs.
Native projects that belong to the application. CapacitorJS makes Android and iOS projects first-class application code. Teams can version, open, debug, configure, and extend them with standard native tools as store requirements, SDKs, signing, and dependencies evolve independently from Meteor.
A decoupled, gradual integration. Meteor coordinates its web build, runtime, Hot Code Push, and commands, while applications control Capacitor versions, npm plugins, configuration, and native projects. Native tooling can evolve without waiting for Meteor releases. Existing Cordova applications remain supported, adoption is opt-in, and compatibility with many Cordova plugins provides a gradual migration path.
A shared model that still matters. Keeping most application logic in one language and project reduces duplicated work and context switching. It also gives AI tools a consistent codebase within limited context windows for implementation, debugging, testing, browser and device automation, and development tooling.
The goal is to preserve Meteor’s multiplatform model with modern native projects, maintained plugins and APIs, and a stronger mobile foundation.
Implementation
The work is divided into two PRs:
- Meteor core integration and documentation: View
meteor/meteor#14633 - Native example applications: View
meteor/examples#47
The core PR contains CLI, build system, native runtime, Hot Code Push, and documentation changes. The examples PR validates complete native workflows through three applications. Both are ready for review and experimentation, although APIs and workflows may change before the first beta.
This work is also becoming a real-world foundation for other modern tool integrations. A Tauri integration follow-up invites contributors to exercise the same extension APIs, keep tool-specific behavior outside Meteor core, and report missing generic capabilities. This lets concrete integrations shape the contract instead of designing every hook in abstraction.
Features
Future published workflow
After package release, applications will enable CapacitorJS with the capacitor package. Existing Cordova projects can keep their setup, so migration remains optional.
Published applications will use familiar Meteor commands:
meteor add capacitor
meteor add-platform android
meteor run android
The same flow will work for iOS:
meteor add-platform ios
meteor run ios
Meteor will prepare the web application, create or update the native project, synchronize plugins, and start the platform. The result remains a standard CapacitorJS project usable through native tooling. For current checkout commands, follow core PR manual setup.
Bundled and livereload modes after release
Bundled mode will be default: application starts with included assets and keeps Meteor’s Hot Code Push support. Build mode remains separate: meteor run defaults to development, while meteor run --production validates production bundle.
During development, Capacitor’s livereload mode will load directly from the running Meteor server:
METEOR_CAPACITOR_MODE=livereload meteor run android
This provides a faster feedback cycle through Capacitor’s native development capabilities. Core PR manual setup documents current checkout workflow, Android --mobile-server, and bundled HCP testing.
Meteor Hot Code Push
The @meteorjs/capacitor runtime preserves the Hot Code Push behavior Meteor users expect. Special thanks to @banjerluke, whose work on capacitor-meteor-webapp became the basis for this implementation.
Compatible web updates can ship without rebuilding and publishing the complete native application. This remains part of Meteor instead of requiring a separate live-update service such as Capgo, reducing migration work.
Capacitor configuration and plugins
Applications use standard capacitor.config.js. Like rspack.config.js, it can return dynamic configuration based on development or production mode, platform, server URL, and native run mode.
Capacitor plugins keep their normal npm installation and import flow. Applications own their versions, while Meteor synchronizes Android and iOS changes during native builds. Projects stay close to standard CapacitorJS documentation without Meteor-specific plugin versions.
Native projects and extensible tooling
Android and iOS projects live in the application root instead of .meteor, follow standard CapacitorJS structure, and can be versioned, opened in Android Studio or Xcode, debugged natively, configured directly, and extended with Swift, Java, or Kotlin. Native changes remain explicit and persistent instead of disappearing with replaceable generated output.
Meteor owns the web application and build. CapacitorJS owns the surrounding native projects. Both can follow their normal ecosystems.
This work also lets external packages connect with Meteor’s CLI and build lifecycle through stable integration points. CapacitorJS is the first integration using this foundation, which can support other platforms without spreading tool-specific logic through Meteor core. Like Rspack, this approach preserves Meteor-specific capabilities while delegating general tooling to broader, specialized ecosystems.
This direction was also influenced by @wreiske, who experimented with packaging Meteor applications for desktop using Tauri. We plan to keep exploring this possible integration, although its scope and timing remain undecided.
Automated native verification with E2E Maestro
Native support needs more than successful builds. Maestro end-to-end smoke flows for Android and iOS complement Playwright coverage, exercising real applications across native runtime, plugins, Meteor data flows, and updates.
This continues Meteor’s commitment to accurate automated verification across the framework. Native development previously lacked coverage at this level, making updates fragile and creating avoidable work. E2E tests turn expected behavior into executable use cases, document device flows through code and visible steps, build shared understanding, and preserve quality over time through automated signals and infrastructure.
Clear E2E flows also give human contributors and AI agents well-described context and constraints to make changes, validate results, and correct themselves. Maestro extends Meteor’s modernized testing pipelines with a sustainable pattern for native development.
Example showcase: Meteor Drop
The examples PR includes Stock Scanner, Civic Snap, and Meteor Drop. It contains per-app details, screenshot, launcher commands, and manual contributor setup. Here, we focus on Meteor Drop because it shows one complete native application flow rather than an isolated technical fixture.
Full native application: Meteor Drop
Tech stack: Meteor, Konsta UI, CapacitorJS
A four-in-a-row mobile game with solo CPU play and live rooms. It starts as a complete mobile app, not a narrow plugin fixture: players navigate Konsta UI screens, play against CPU or join a live DDP room, share results through native share sheet, receive haptic feedback, inspect native runtime state, and accept a Meteor Hot Code Push update.
All three applications test more than compilation through practical Capacitor configuration, Meteor data and real-time behavior, plugin browser fallbacks, Hot Code Push, Playwright browser coverage, and Maestro native flows for Android and iOS. Together, they cover application updates, browser automation, and native device behavior inside complete applications.
Try it and help us prepare the beta
Sharing the working checkout lets developers run prepared examples, try their applications, validate migrations, and report results before the official release slot while the current queue continues.
It is also an invitation to learn Meteor core development: select a branch, run its Meteor executable, reproduce behavior, validate changes, improve documentation, and propose fixes. More developers using this workflow strengthens both CapacitorJS support and its long-term contributor base.
Teams test new infrastructure at different speeds, so checkout access provides useful feedback before a published beta. It does not replace that beta, which will let a broader group test through a published Meteor CLI release without building Meteor from source.
Publishing now would split work across the same package, CLI, build, and release areas, increasing coordination and conflicts. Current priorities are:
- Meteor 3.5.x patches: stabilize Change Streams and DDP runtime enhancements, plus Rspack bundle performance for large applications
- Meteor 3.6: complete Rspack 2.x, TypeScript integration, full package coverage, CLI improvements, and related work
Meteor 3.6 could still include the first published experimental CapacitorJS beta, depending on this queue and checkout feedback. This remains a possibility, not a commitment. It follows our release cadence: keep current work focused while exposing later work early enough for real-world testing.
This path brings years of CapacitorJS experiments, migration knowledge, Hot Code Push contributions, and Cordova plugin reports into a supported Meteor workflow. If you encounter questions, setup problems, or unfamiliar parts of Meteor development, ask in this thread or the relevant PR. Maintainers will help with the process, while those questions reveal edge cases and improve guidance for future contributors.
Choose one of two paths:
Run prepared native examples
To see complete applications and native interactions quickly, clone both PR branches and run the examples launcher. It prepares local package links, platform project, and native run command.
npm run run:native -- meteor-drop android -- --mobile-server http://10.0.2.2:3000
The examples PR Hands-on walkthrough covers checkout layout, platform prerequisites, launcher options, bundled HCP, and manual contributor workflow. Launcher does not clone or switch branches, so prepare both checkouts first.
Try your own Meteor app or contribute to integration
Use core PR manual setup for any Meteor app. It covers checkout executable, meteor add capacitor, capacitor.config.js, add-platform, bundled HCP, Android --mobile-server, livereload, plugins, and local @meteorjs/capacitor linking.
This workflow remains experimental, so test it in separate branches and applications rather than as a production dependency.
Share early-access results in this thread so we can compare setups, migrations, and recurring gaps. Propose code changes through either PR. Useful feedback includes:
- New CapacitorJS projects and Cordova migrations: what worked, needed adaptation, or blocked progress
- Cordova plugins reused, replaced, or unable to migrate, with relevant Capacitor and native configuration
- Android and iOS results on simulators and devices, including Android Studio and Xcode workflows
- Bundled and livereload modes, Hot Code Push, browser fallbacks, existing packages, and Meteor data flows
- Reproductions with expected and actual behavior, logs, screenshots, recordings, and ideally a small repository
Successful migrations also show what is covered. AI tools can help produce smaller reproductions, but reports should explain setup, migration context, expected behavior, and actual result.
Public beta will need broader testing in real, large, and long-running applications. Existing Cordova projects are especially valuable for revealing migration gaps and behaviors Meteor must preserve. Early checkout access also helps teams plan before the release slot is decided.
Reports are easier to investigate while checkout and beta work is active. Later feedback will still be reviewed, but may take longer as focus moves elsewhere. Recent bundler improvements followed this pattern through long betas across three minor versions and release delays when testing found issues. CapacitorJS can likewise learn through checkouts before a focused beta stabilization period.
Your participation will help this integration serve the range of Meteor applications in use today. We will listen and adjust, while asking for clear communication, patience, and an understanding of the open-source release cycle.
Part of Meteor’s modernization
Strong applications depend on strong tools. Work since the Node.js transition is one of Meteor’s strongest development periods since its early years show our continued commitment to keeping the framework reliable, mature, and alive.
Meteor’s modernization included the Node.js upgrade and move from Fibers to Promises, bundler optimizations, Rspack integration, and runtime performance work. TypeScript and testing improvements continue, while the native stack has needed attention for a long time.
The same principle connects these efforts: preserve Meteor’s valuable capabilities and integrate maintained external tools with broader ecosystems and specialized expertise.
CapacitorJS updates native development while keeping shared JavaScript, Meteor data flows, reactivity, familiar commands, and Hot Code Push. It makes Meteor’s original multiplatform promise practical for today’s native ecosystem.