Mike Miller
March 10, 2025

In 2025, developers building cross-platform mobile apps face three main contenders: ByteDance's Lynx, Meta's React Native, and Google's Flutter. Each framework offers a different approach to the same challenge: how to build high-quality apps that work across platforms while keeping development efficient.
Lynx, newly open-sourced by ByteDance in March 2025, emerged from TikTok's performance needs. It features an innovative dual-thread JavaScript engine and embraces web standards with full CSS support. React Native continues to be the go-to solution for JavaScript developers, with its improved architecture and massive ecosystem. Flutter has gained significant traction with its Dart-based approach that ensures consistent visuals across all platforms.
This comparison examines how these frameworks stack up in terms of technical architecture, developer experience, and real-world adoption. For development teams, the best choice depends on your existing skills, performance requirements, and which platforms you're targeting.
While React Native and Flutter dominate with their mature ecosystems, Lynx brings fresh ideas to the table that could change how we approach cross-platform development. Let's explore what makes each framework unique and which might be the right fit for your next project.
We explore this more deeply in Why ByteDance Built Lynx (Because React Native Left a Gap).
| Feature | Lynx | React Native | Flutter |
|---|---|---|---|
| Origin | ByteDance (TikTok's parent company), open-sourced in 2025 | Facebook (Meta), launched in 2015 | Google, stable since 2018 |
| Purpose | Performance-first approach for native apps using web technologies | Unify web and mobile development using JavaScript and React | High-performance UI toolkit for consistent cross-platform UIs using Dart |
| Technical Architecture | Dual-thread architecture: PrimJS on main thread (UI), QuickJS in background (logic) | JavaScript bridge (historically), improved with Hermes engine and Fabric architecture | Custom Skia/Impeller rendering engine controlling every pixel |
| Rendering Approach | Native UI components by default; also supports custom pixel-perfect rendering mode | Native UI components, ensuring platform look and feel | Custom rendering (controls every pixel) for consistent UIs |
| Performance Features | Instant First-Frame Rendering (IFR), Main Thread Script (MTS) for synchronous UI updates, 60fps+ animations | Improved with Hermes engine, requires optimizations like interaction manager for heavy work | GPU-accelerated rendering, JIT/AOT compiled Dart, generally smooth 60fps UI |
| App Size & Overhead | Lightweight: QuickJS engine (~<1MB) + Lynx core | Moderate: requires JS VM and bundle, typically a few MB | Larger: includes Dart runtime and Skia engine, "Hello World" can be 5-10+ MB |
| Platform Coverage | Mobile (Android/iOS) and Web officially, with experimental desktop support | Mobile (Android/iOS) officially, Web via React Native Web, unofficial desktop support | Mobile, Web, and Desktop (Windows, macOS, Linux) all officially supported |
| UI Definition | JSX/HTML-like syntax with tags and standard CSS/SCSS (including flexbox, grid, animations) | JSX components with limited CSS-like styling | Dart code with widget trees, no HTML/CSS |
| Styling Capabilities | Full CSS support including selectors, media queries, animations; can use Tailwind CSS | Limited CSS subset, styling via JavaScript objects | No CSS, UI styled through Dart code and widget properties |
| Framework Compatibility | Framework-agnostic with React bindings at launch; plans for Vue and Svelte support | Tied to React framework | Flutter's own framework and widget system |
| Developer Experience | Web-like workflow, Chrome DevTools-style debugging, Rspack bundler, fast refresh | Fast Refresh, debugging via Chrome DevTools or Flipper, optionally Expo for easier setup | Hot Reload, comprehensive DevTools, requires learning Dart |
| Ecosystem & Community | Limited and nascent; few third-party libraries | Mature with thousands of npm packages, large active community | Strong and growing, official and community packages on pub.dev |
| Real-world Adoption | Used in TikTok (Search, Shopping, Live streaming features) | Widely adopted (Instagram, Walmart, UberEats, Bloomberg), ~38% of cross-platform devs | Growing adoption (Alibaba, Google Pay, eBay, BMW), ~42% of cross-platform devs |
| Integration in Existing Apps | Designed for incremental adoption, proven in TikTok's hybrid approach | Supports incremental adoption in existing native apps | Add-to-app API but typically heavier integration |
| Unique Strengths | • Web-native approach with low learning curve • High-performance UI without sacrificing native components • Flexible rendering options (native or custom) • Full CSS support | • Massive ecosystem and community support • Leverages React knowledge and JS ecosystem • Native look and feel by default • Large talent pool available | • Consistent UI across all platforms • Superior performance for complex graphics • Comprehensive platform support • Strong tooling integration |
| Best For | • Web developers building native apps • Apps needing smooth handling of rich dynamic content • Projects targeting Web+Mobile with unified codebase | • Teams already invested in React • Incremental adoption in existing apps • Projects needing native look and feel | • Brand-consistent UIs across platforms • Complex UIs and animations • Projects targeting multiple platforms including desktop |
| Current Viability | Promising technically but with uncertain adoption; needs ecosystem growth | Established with ongoing improvements, expected to remain dominant | Actively evolving with Google backing, likely to grow in presence |
| Future Outlook | Could remain niche or grow into a serious competitor depending on community adoption and ByteDance's continued investment | Likely to remain a top choice due to Meta backing and extensive community | Expected to expand market presence, possibly overtaking RN in some areas |
Lynx introduces valuable innovations with its dual-thread architecture and web-focused approach, especially appealing to those with strong web development skills. However, its nascent ecosystem and limited adoption outside ByteDance mean it remains a niche solution for now. React Native and Flutter continue to dominate with their mature tooling and communities, with Flutter gaining momentum for new projects requiring consistent UIs across platforms.

Expo Push Notifications: The Complete Implementation Guide (SDK 52+)
Expo push notifications are alerts sent from a server to a user's phone, even when the app isn't open. To set them up, install the expo-notifications library, ask the user for permission, and get a unique push token for their device. Your server sends a message to Expo's push service with that token, and Expo delivers it through Apple or Google. Push notifications only work on real phones, not simulators. Local notifications are different — they're scheduled by the app itself for things like reminders. You can also route Expo push through services like Courier to add email, SMS, and Slack fallbacks.
By Kyle Seyler
February 24, 2026

Best Email API Providers for Developers in 2026: SendGrid vs Postmark vs Mailgun vs SES vs Resend
Your email provider sticks with you longer than most technical decisions. Courier handles notification infrastructure for thousands of teams, so we went deep on the six email providers that show up most: SendGrid, Postmark, Mailgun, Amazon SES, Resend, and SMTP. This guide covers real API primitives, actual code from each provider's docs, Courier integration examples with provider overrides, and an honest read on where each developer experience holds up and where it breaks down. We also asked Claude to review every API and tell us which one it would wire up first. The answer surprised us.
By Kyle Seyler
February 23, 2026

The Courier MCP Server Is Open Source. Here's How It Actually Works.
Courier's MCP server is open source at github.com/trycourier/courier-mcp. It connects AI coding tools like Cursor and Claude Code to your Courier account so they can send messages, manage users, and install SDKs without hallucinating API details. This post walks through the actual codebase: how 16 tool classes are registered (and how a config allowlist gates most of them), why we pull installation guides from GitHub at runtime instead of bundling them, how the DocsTools class generates live JWTs alongside setup instructions, and what the SdkContextTools class does in the repo to prevent v7/v8 SDK conflicts (even though it isn't wired into the server yet).
By Mike Miller
February 06, 2026
© 2026 Courier. All rights reserved.