Curi is a JavaScript router for single-page applications

Curi cares about routing, not how you render.

A router has two main pieces: a history object for controlling navigation and a routes array of the valid routes for an application.

import Browser from '@hickory/browser';

const history = Browser();
const routes = [
  { name: 'Home', path: '', ... },
  { name: 'User', path: 'u/:userID', ... },
  // ...
  { name: 'Not Found', path: '(.*)', ... }
];

A router is created by passing the history and routes to the curi function from the @curi/router package.

import { curi } from '@curi/router';

const router = curi(history, routes);

How you render depends on what framework you are using.

For React applications, you would use the <CuriProvider>, which automatically re-renders your application after navigation. This works with both React DOM and React Native.

import { CuriProvider } from "@curi/react";
        
ReactDOM.render((
  <CuriProvider router={router}>
    {({ response }) => {
      const { body:Body } = response;
      return <Body response={response} />;
    }}
  </CuriProvider>
), holder);

With Vue, the CuriPlugin sets up responsive rendering.

import { CuriPlugin } from "@curi/vue";
        
Vue.use(CuriPlugin, { router });
const vm = new Vue({
  el: '#root',
  template: '<app />',
  components: { app }
});

// app.html
<template>
  <component
    :is="$curi.response.body"
    :response="$curi.response"
  />
</template>

Svelte apps can use the store to interact with the router. The store is automatically updated after navigation to trigger re-renders.

import { curiStore } from "@curi/svelte";
const store = curiStore(router);

const view = new app({ target, store });

// app.html
<svelte:component
  this={$curi.response.body}
  response={$curi.response}
/>

While React, Vue, and Svelte are currently the only frameworks with "official" packages, with a little work Curi can work with most frameworks (and vanilla JavaScript)!

Ready to learn more? Check out the getting started guide.