A tiny vanilla js router

Usage no npm install needed!

<script type="module">
  import veryTinyRouter from '';


Very Tiny Router

A simple vanilla js router written in modern javascript. You can use it to build lightweight SPAs or enhance your traditional multi page websites.



npm install very-tiny-router


You can also include very-tiny-router directly in the browser. Download this repository and place it in the root folder of your website. Then you can either use a iife:

<script src="./very-tiny-router/dist/index.iife.js"></script>
  const router = new Router()

or a javascript module:

<script type="module">
  import Router from './very-tiny-router/dist/index.esm.js'


Create a new Router and add Routes:

import Router from 'very-tiny-router'

const router = new Router()
router.route('/', () => console.log('Home'))
router.route('/about', () => console.log('About'))
router.route('/projects/:id', ({ id }) => console.log(`Show project ${id}`))
router.route('*', () => console.log('Not found!'))

// In most cases, you probably want the router to handle the initial route.

Handle Link Navigation:

<a class="router-link" href="/">Home</a>
<a class="router-link" href="/about">About</a>
<a class="router-link" href="/projects/test">This one project</a>

To prevent the links from actually changing the page we have to intercept the click events and push/replace a route instead.

document.querySelectorAll('a.router-link').forEach(el =>
  el.addEventListener('click', event => {



You can define the routes directly when creating the router (or use the route() method) and set the history scrollRestoration.

const router = new Router({
  routes: [
    { path: '/', action: () => console.log('Home') },
    { path: '/user/:name', action: ({ name }) => console.log(`Hello ${id}!`) }
  scrollRestoration: 'auto' // default is 'manual'

Push a new Route


Replace the current Route


Add a new Route

router.route('/path', () => {
  // Do something ...

Add a new Dynamic Route

You can use one or more dynamic segments (denoted by a colon :). The dynamic segments will then be available in the route's action callback.

const action = params => {
  console.log(`Hello ${params.firstName} ${params.lastName}!`)
router.route('/user/:firstName/:lastName', action)

Handle initial route

In most cases you probably want the router to handle the initial route:

const router = new Router()
router.route('*', () => console.log('hello world!'))
// This will call the route immediately:

In some cases you may want to handle the initial route differently (e.g.: no smooth scrolling):

const router = new Router()
router.route('projects/:id', (params, initial) => {
  const el = document.getElementById(
  el.scrollIntoView({ behavior: initial ? 'auto' : 'smooth' })

Use the current Route

You can also use the current route anywhere in your project:

// router.js
import Router from 'very-tiny-router'
export default const router = new Router({
  routes: [
    { path: '/', () => { /* ... */ } },
    { path: '/user/:name', () => { /* ... */ } }
// another-file.js
import router from './router.js'

window.addEventListener('click', () => {
  if (router.currentRoute.path === '/') {
    console.log('Welcome home!')
  } else {
    console.log(`Welcome ${}`)

Catch all / 404 Not found Route

You can use the asterisk * to match any route that is not matched by a previous route. See important for the asterisk's limitations.

router.route('*', () => console.log('Not found!'))


Execute a callback before or after each route. This are simple hooks, no navigation guards. So you can't use them to redirect or cancel routes. The callbacks receive a route object as an argument containing the path, pattern and params.

router.beforeEach(route => console.log(`Changing to path: ${route.path}`))
router.afterEach(route => console.log(`Changed to path: ${route.path}`))


  • very-tiny-router uses HTML5 history mode only, so make sure your server is setup correctly (see vue router's explanation).
  • The asterisk * can only be used to catch all routes. It is not possible to use it like this '/user-*'.