Frameworks like React Native and Flutter have long dominated cross-platform development, but Lynx JS introduces a fresh approach that seamlessly bridges web and mobile development, built on top of the React Engine.
And lately, I’ve been busy balancing everything: work, life & hobby. Suddenly, just got news about new development tools from TikTok named Lynx.
Yes, you heard it! Named from a medium-sized wildcat known for its distinctive appearance and elusive nature.
From that moment made my curiosity to try! And here’s the review, the story of me trying Lynx.js
Introduction: Release Date
5th March 2025 marked the birth of Lynx.js, a family of technologies empowering developers to use their existing web skills to create truly native UIs for both mobile and web from a single codebase. Designed for diverse use cases and rich interactivity, Lynx delivers vibrant and engaging UIs for large-scale apps like TikTok, featuring a speedy, versatile rendering engine, performance-driven dual-threaded UI programming, modern Rust-based tooling, and more!
One week after the release date, I got an update post from daily.dev about the new JavaScript framework Lynx.js, right after that I’m starting to try it.
Initial Plan: Blog App
I was thinking to learn Lynx.js, not just randomly trying its component without planning what the app was going to make. Then the idea that comes to my mind is creating a blog app, a simple yet powerful implementation for a simple CRUD operation.
Looking for some inspiration on Dribble, I found this perfect UI Design Blog App by Syed Raju https://dribbble.com/shots/20805109-Blog-App
Configuration: Blog App
To start development, what we need is to install LynxExplorer.
Then run this command to create the project
npm create rspeedy@latest
Full documentation, quick start of Lynx.js right here
Fast-forward, after the configuration setup is finished, time to dive in.
Building: Blog App
Because Lynx.js uses React Engine, all the existing components are similar to React Native’s components.
Let’s take a look at how we place all elements in Lynx.js.
// hello world in lynx
export const App = () => {
return (
<view style="padding:5px;width:100%; height:100%;">
<text className="title">Hello Readers</text>
</view>
);
};
//hello world in react native
export const App = () => {
return (
<View style="padding:5px;width:100%; height:100%;">
<Text className="title">Hello Readers</Text>
</View>
);
};
One of the differences is a capitalized letter at the first. Lynx.js brings a vibe of how you code for the web starts with lowercase.
Review: Pros & Cons
What else can we see from Lynx.js?
Gradient background, all along in React Native, to produce a gradient, we need help from another library or/3rd party. With Lynx.js, we can easily do that as we do on the web. Define a custom class, then set the value.
/* global.css */
.bg-midnight-gradient {
background: linear-gradient(
to right,
rgb(29, 78, 216),
rgb(30, 64, 175),
rgb(17, 24, 39)
);
}
You may import it into your components, like this, set the class name we defined in the component.
const Header = () => {
return (
<view
class="bg-midnight-gradient container"
>
<text class="text-white">
Blogbust
</text>
</view>
);
};
export default Header;
Another one is how to define route/navigation currently, when I write this review, the only way to handle multiple pages in Lynx is using react-router.
import { useNavigate, useLocation } from 'react-router';
import { IMAGE } from '../../constants/images.ts';
const BottomNavigation = () => {
const navigate = useNavigate();
const location = useLocation();
const handleNavigation = (path: string) => {
navigate(path);
};
const isActive = (path: string) => {
return location.pathname === path;
};
return (
<view>
<view>
{/* Home Menu */}
<view
bindtap={() => handleNavigation('/home')}>
<image
src={
isActive('/home') || isActive('/')
? IMAGE.ICON_HOME_ACTIVE
: IMAGE.ICON_HOME
}
style={{
width: '20px',
height: '20px',
}}
/>
<text>
Home
</text>
</view>
{/* Profile Menu */}
<view
bindtap={() => handleNavigation('/profile')}
>
<image
src={
isActive('/profile')
? IMAGE.ICON_PROFILE_ACTIVE
: IMAGE.ICON_PROFILE
}
style={{
width: '20px',
height: '20px',
}}
/>
<text>
Profile
</text>
</view>
</view>
</view>
);
};
export default BottomNavigation;
What if we need a library to use, for example, TailwindCSS?
To use a library is kinda tricky at the moment, still lacks its documentation, notes review from the community/developers themselves.
But yes, you can leverage 3rd party to use like any other JavaScript framework/library. Here’s how I managed to integrate TailwindCSS into Lynx’s project.
Install the necessary package first, like rsbuild-plugin-tailwind and the tailwindcss itself. Fyi, Lynx.js adapts rspack for the building tool called lynxjs/rspeedy based on Rust.
npm i tailwindcss @lynx-contrib/tailwind-preset rsbuild-plugin-tailwindcss
Create a tailwindcss configuration as usual, then import the latest rest libraries into lynx.config.ts
import { defineConfig } from '@lynx-js/rspeedy';
import { pluginTailwindCSS } from 'rsbuild-plugin-tailwindcss';
export default defineConfig({
plugins: [
...,
pluginTailwindCSS(),
],
});
Now, we can use className in our component similarly to how we use Tailwind for the web. Cool right?
import Header from '../components/header/index.tsx';
import Horizontal from '../components/scroller-item/Horizontal.tsx';
import Vertical from '../components/scroller-item/Vertical.tsx';
import Scroller from '../components/scroller/index.tsx';
import { blogs } from '../constants/blogs.ts';
import { categories } from '../constants/categories.ts';
import { IMAGE } from '../constants/images.ts';
const Home = () => {
return (
<>
<Header />
<view className="bg-stone-100">
<Scroller
oritentation="horizontal"
styles={{
width: 'calc(100% - 1px)',
height: '100px',
paddingBottom: '20px',
paddingTop: '20px',
paddingLeft: '12px',
paddingRight: '12px',
borderRadius: '1px',
}}
>
{categories.map((item, index) => (
<Horizontal index={index} item={item} />
))}
</Scroller>
</view>
<view className="h-full p-4">
<view className="flex justify-between items-center">
<text className="font-bold leading-normal text-2xl">Games</text>
<image src={IMAGE.ICON_FILTER} className="w-6 h-6" />
</view>
<Scroller
oritentation="vertical"
styles={{
width: 'calc(100% - 1px)',
height: 'calc(100% - 280px)',
paddingBottom: '20px',
}}
>
{blogs.map((item, index) => (
<Vertical item={item} />
))}
</Scroller>
</view>
</>
);
};
export default Home;
Conclusion: IMO
After exploring Lynx.js, it’s clear this framework brings an interesting approach to web development and shines in certain areas, even currently, as I write this blog, still in beta version.
However, Lynx.js still has room to grow. Looking ahead, I hope future updates will bring:
- More comprehensive documentation, especially for third-party integrations
- Native navigation solutions beyond React-Router
- Streamlined library integration processes
- Expanded component library and styling options
- Better community resources and examples
Lynx.js shows promise with its web-like approach to development, but it needs continued refinement to reach its full potential. The foundation is solid, and with active development and community growth, it could become a compelling option for developers seeking performance and familiar web paradigms.
Thank you for being a part of the community
Before you go:
- Be sure to clap and follow the writer ️👏️️
- Follow us: X | LinkedIn | YouTube | Newsletter | Podcast | Differ | Twitch
- Start your own free AI-powered blog on Differ 🚀
- Join our content creators community on Discord 🧑🏻💻
- For more content, visit plainenglish.io + stackademic.com
