The Rise of Lynx.js: A Newcomer JavaScript Framework Fueling TikTok’s Innovation
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@latestFull 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.
Get Raihan Nismara’s stories in your inbox
Join Medium for free to get updates from this writer.
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-tailwindcssCreate 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









