Top Related Projects
Declarative routing for React
🥢 A minimalist-friendly ~2.1KB routing for React and Preact
🧭 Declarative, asynchronous routing for React.
🤖 Fully typesafe Router for React (and friends) w/ built-in caching, 1st class search-param APIs, client-side cache integration and isomorphic rendering.
Quick Overview
Universal Router is a simple yet powerful routing solution for JavaScript applications. It's designed to work with both client-side and server-side environments, providing a unified approach to routing across different platforms. The library is lightweight and has zero dependencies, making it an excellent choice for various JavaScript projects.
Pros
- Platform-agnostic: Works in both browser and Node.js environments
- Lightweight and zero dependencies
- Supports nested routes and parameterized routing
- Flexible and customizable with middleware support
Cons
- Less feature-rich compared to some larger routing libraries
- Smaller community and ecosystem compared to more popular routing solutions
- May require additional setup for complex routing scenarios
- Limited built-in support for advanced routing patterns
Code Examples
- Basic route definition:
import UniversalRouter from 'universal-router';
const routes = [
{ path: '/', action: () => '<h1>Home</h1>' },
{ path: '/about', action: () => '<h1>About</h1>' },
{ path: '/users/:id', action: ({ params }) => `<h1>User ${params.id}</h1>` }
];
const router = new UniversalRouter(routes);
- Handling route resolution:
router.resolve('/users/123').then(html => {
document.body.innerHTML = html;
});
- Using middleware:
const routes = [
{
path: '/admin',
action: () => '<h1>Admin Area</h1>',
children: [
{
path: '/users',
action: () => '<h2>Manage Users</h2>',
}
],
async middleware(context, next) {
if (!isAuthenticated()) {
return { redirect: '/login' };
}
return await next();
}
}
];
Getting Started
To start using Universal Router in your project:
-
Install the package:
npm install universal-router
-
Import and set up your routes:
import UniversalRouter from 'universal-router'; const routes = [ { path: '/', action: () => '<h1>Home</h1>' }, { path: '/about', action: () => '<h1>About</h1>' } ]; const router = new UniversalRouter(routes); // Resolve a route router.resolve(location.pathname).then(html => { document.body.innerHTML = html; });
-
For more advanced usage and configuration options, refer to the official documentation.
Competitor Comparisons
Declarative routing for React
Pros of React Router
- More comprehensive feature set, including nested routing and route-based code splitting
- Larger community and ecosystem, with extensive documentation and third-party integrations
- Tighter integration with React, offering hooks like
useParams
anduseNavigate
Cons of React Router
- Steeper learning curve due to its more complex API and concepts
- Larger bundle size, which may impact initial load times for smaller applications
- Less flexibility for use outside of React applications
Code Comparison
React Router:
import { BrowserRouter, Route, Switch } from 'react-router-dom';
<BrowserRouter>
<Switch>
<Route path="/about" component={About} />
<Route path="/" exact component={Home} />
</Switch>
</BrowserRouter>
Universal Router:
import UniversalRouter from 'universal-router';
const router = new UniversalRouter([
{ path: '/about', action: () => <About /> },
{ path: '/', action: () => <Home /> }
]);
Universal Router offers a more lightweight and flexible approach, suitable for various JavaScript environments. It provides a simpler API but lacks some of the React-specific features and conveniences of React Router. React Router, on the other hand, is more tightly integrated with React and offers a richer set of features specifically designed for React applications, albeit with a more complex API and larger footprint.
Pros of Reach Router
- Built-in accessibility features, including focus management
- Relative linking and nested routes for easier navigation
- Smaller bundle size, optimized for performance
Cons of Reach Router
- Less flexible for complex routing scenarios
- Limited support for code splitting and lazy loading
- Fewer configuration options compared to Universal Router
Code Comparison
Reach Router:
import { Router } from "@reach/router"
<Router>
<Home path="/" />
<Dashboard path="dashboard" />
<Profile path="profile/:id" />
</Router>
Universal Router:
import UniversalRouter from 'universal-router'
const routes = [
{ path: '/', action: () => <Home /> },
{ path: '/dashboard', action: () => <Dashboard /> },
{ path: '/profile/:id', action: ({ params }) => <Profile id={params.id} /> }
]
const router = new UniversalRouter(routes)
Both routers offer declarative routing for React applications, but Reach Router focuses on simplicity and accessibility, while Universal Router provides more flexibility and control over routing logic. Reach Router's syntax is more concise and React-specific, whereas Universal Router offers a more generic approach that can be used with various view libraries. The choice between the two depends on project requirements, with Reach Router being ideal for straightforward React apps and Universal Router better suited for complex routing scenarios or non-React projects.
🥢 A minimalist-friendly ~2.1KB routing for React and Preact
Pros of wouter
- Lightweight and minimalistic, with a smaller bundle size
- Simple API that's easy to understand and use
- Supports both hash-based and history-based routing out of the box
Cons of wouter
- Less feature-rich compared to Universal Router
- May require additional libraries for more complex routing scenarios
- Limited documentation and community support
Code Comparison
wouter:
import { Route, Switch } from "wouter";
<Switch>
<Route path="/users/:id" component={UserProfile} />
<Route path="/about" component={About} />
</Switch>
Universal Router:
import UniversalRouter from 'universal-router';
const router = new UniversalRouter([
{ path: '/users/:id', action: () => <UserProfile /> },
{ path: '/about', action: () => <About /> }
]);
Universal Router offers a more programmatic approach to routing, while wouter provides a declarative JSX-based syntax. wouter's simplicity makes it easier to understand and implement for basic routing needs, but Universal Router's flexibility allows for more complex routing scenarios and middleware integration.
Both libraries have their strengths, and the choice between them depends on the specific requirements of your project. wouter is ideal for smaller applications or those prioritizing simplicity, while Universal Router is better suited for larger, more complex applications that require advanced routing capabilities.
🧭 Declarative, asynchronous routing for React.
Pros of Navi
- Built-in code splitting and lazy loading support
- Declarative routing with React hooks
- Supports static site generation and server-side rendering
Cons of Navi
- Steeper learning curve due to unique concepts and API
- Less community adoption compared to Universal Router
Code Comparison
Navi:
import { createSwitch, createRoute } from 'navi';
const routes = createSwitch({
'/': createRoute({ view: <HomePage /> }),
'/about': createRoute({ view: <AboutPage /> }),
});
Universal Router:
const routes = [
{ path: '/', action: () => <HomePage /> },
{ path: '/about', action: () => <AboutPage /> },
];
Key Differences
- Navi uses a more declarative approach with
createSwitch
andcreateRoute
- Universal Router uses a simpler array-based configuration
- Navi's routing is more tightly integrated with React components
- Universal Router is more flexible and can be used with various view libraries
Use Cases
- Choose Navi for React projects requiring advanced features like code splitting and SSR
- Opt for Universal Router for simpler routing needs or non-React projects
Community and Ecosystem
- Universal Router has a larger user base and more GitHub stars
- Navi has fewer contributors but offers more React-specific features
🤖 Fully typesafe Router for React (and friends) w/ built-in caching, 1st class search-param APIs, client-side cache integration and isomorphic rendering.
Pros of TanStack Router
- More comprehensive routing solution with built-in type safety
- Supports both client-side and server-side routing
- Offers advanced features like nested routing and route loaders
Cons of TanStack Router
- Steeper learning curve due to its more complex API
- Larger bundle size compared to Universal Router
- May be overkill for simpler applications
Code Comparison
Universal Router:
const router = new UniversalRouter([
{ path: '/home', action: () => '<h1>Home</h1>' },
{ path: '/about', action: () => '<h1>About</h1>' }
]);
router.resolve('/home').then(html => {
document.body.innerHTML = html;
});
TanStack Router:
const routeTree = rootRoute.addChildren([
homeRoute,
aboutRoute
]);
const router = new Router({ routeTree });
function App() {
return <RouterProvider router={router} />;
}
Summary
Universal Router is a lightweight, flexible routing solution suitable for simple applications. TanStack Router offers a more robust, type-safe routing system with advanced features, making it ideal for complex applications but potentially overwhelming for smaller projects.
Convert designs to code with AI
Introducing Visual Copilot: A new AI model to turn Figma designs to high quality code using your components.
Try Visual CopilotREADME
Universal Router
A simple middleware-style router that can be used in both client-side and server-side applications.
Visit Quickstart Guide (slides) | Join #universal-router on Gitter to stay up to date
Features
- It has simple code with only single path-to-regexp dependency.
- It can be used with any JavaScript framework such as React, Vue, Hyperapp etc.
- It uses the same middleware approach used in Express and Koa, making it easy to learn.
- It supports both imperative and declarative routing style.
- Routes are plain JavaScript objects with which you can interact as you like.
What users say about Universal Router
Just switched a project over to universal-router. Love that the whole thing is a few hundred lines of flexible, easy-to-read code.
-- Tweet by Greg Hurrell from Facebook
It does a great job at trying to be universal â it's not tied to any framework, it can be run on both server and client, and it's not even tied to history. It's a great library which does one thing: routing.
-- Comment on Reddit by @everdimension
Installation
Using npm:
npm install universal-router --save
Or using a CDN like unpkg.com or jsDelivr with the following script tag:
<script src="https://unpkg.com/universal-router/universal-router.min.js"></script>
You can find the library in window.UniversalRouter
.
How does it look like?
import UniversalRouter from 'universal-router'
const routes = [
{
path: '', // optional
action: () => `<h1>Home</h1>`
},
{
path: '/posts',
action: () => console.log('checking child routes for /posts'),
children: [
{
path: '', // optional, matches both "/posts" and "/posts/"
action: () => `<h1>Posts</h1>`
},
{
path: '/:id',
action: (context) => `<h1>Post #${context.params.id}</h1>`
}
]
}
]
const router = new UniversalRouter(routes)
router.resolve('/posts').then(html => {
document.body.innerHTML = html // renders: <h1>Posts</h1>
})
Play with an example on JSFiddle, CodePen, JS Bin in your browser or try RunKit node.js playground.
Documentation
Books and Tutorials
- ð ES6 Training Course by Wes Bos
- ð You Don't Know JS: ES6 & Beyond by Kyle Simpson (Dec, 2015)
- ð You might not need React Router by Konstantin Tarkus
- ð An Introduction to the Redux-First Routing Model by Michael Sargent
- ð Getting Started with Relay Modern for Building Isomorphic Web Apps by Konstantin Tarkus
Browser Support
We support all ES5-compliant browsers, including Internet Explorer 9 and above,
but depending on your target browsers you may need to include
polyfills for
Map
,
Promise
and
Object.assign
before any other code.
For compatibility with older browsers you may also need to include polyfills for
Array.isArray
and Object.create
.
Contributing
Anyone and everyone is welcome to contribute to this project. The best way to start is by checking our open issues, submit a bug report or feature request, participate in discussions, upvote or downvote the issues you like or dislike, send pull requests.
Support
- #universal-router on Gitter â Watch announcements, share ideas and feedback.
- GitHub Issues â Check open issues, send feature requests.
- @koistya on Codementor, HackHands or Skype â Private consulting.
Related Projects
- React Starter Kit â Boilerplate and tooling for building isomorphic web apps with React and Relay.
- Node.js API Starter Kit â Boilerplate and tooling for building data APIs with Docker, Node.js and GraphQL.
- ASP.NET Core Starter Kit â Cross-platform single-page application boilerplate (ASP.NET Core, React, Redux).
- Babel Starter Kit â Boilerplate for authoring JavaScript/React.js libraries.
- React App SDK â Create React apps with just a single dev dependency and zero configuration.
- React Static Boilerplate â Single-page application (SPA) starter kit (React, Redux, Webpack, Firebase).
- History â HTML5 History API wrapper library that handle navigation in single-page apps.
- Redux-First Routing â A minimal, framework-agnostic API for accomplishing Redux-first routing.
Sponsors
Become a sponsor and get your logo on our README on Github with a link to your site. [Become a sponsor]
Backers
Support us with a monthly donation and help us continue our activities. [Become a backer]
License
Copyright © 2015-present Kriasoft. This source code is licensed under the MIT license found in the LICENSE.txt file. The documentation to the project is licensed under the CC BY-SA 4.0 license.
Made with ⥠by Konstantin Tarkus (@koistya, blog), Vladimir Kutepov and contributors
Top Related Projects
Declarative routing for React
🥢 A minimalist-friendly ~2.1KB routing for React and Preact
🧭 Declarative, asynchronous routing for React.
🤖 Fully typesafe Router for React (and friends) w/ built-in caching, 1st class search-param APIs, client-side cache integration and isomorphic rendering.
Convert designs to code with AI
Introducing Visual Copilot: A new AI model to turn Figma designs to high quality code using your components.
Try Visual Copilot