npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

noxt-js-middleware

v1.0.6

Published

A lightweight JSX-powered router for Express. Does not depend on React.

Downloads

5

Readme

Noxt.js Middleware

A lightweight, file-based JSX router for Express with zero dependency on React. 🚀

Noxt.js allows you to build server-rendered applications using JSX templating and a simple, file-based routing system. It's designed to be intuitive, flexible, and easy to integrate into any Express project.

See the source on GitHub: noxt-js-middleware

Key Features

  • File-Based Routing: .jsx files that export a route are automatically registered as pages.

  • JSX without React: Use the power and readability of JSX for your server-side templates.

  • Async Data Loading: Fetch data for your pages before they render using a simple params export.

  • Shared Context: Easily pass global data, utilities, and components to your entire application.

Basic Setup

First, install the package:

npm install noxt-js-middleware

Then, integrate it with your Express app. Noxt will scan the specified directory, register all pages and components, and return a router instance.

import express from 'express';
import noxt from 'noxt-js-middleware';

const app = express();

// Initialize the Noxt router
const noxtRouter = await noxt({
  // The directory where your .jsx files live
  directory: 'views',

  // An object that will be available to all components and pages
  context: {
    appName: 'My Awesome App',
    utils: {
      // Your helper functions
      formatDate: (date) => new Date(date).toLocaleDateString(),
    }
  }
});

// Use the router with your Express app
app.use(noxtRouter);

app.listen(3000, () => {
  console.log('Server running on http://localhost:3000');
});

Core Concepts

Components

Any .jsx file found in the directory is treated as a Component.

  • Naming: The component's name is its filename (e.g., UserInfo.jsx becomes UserInfo). It must start with a capital letter and be unique.

  • Export: The component function must be the default export.

  • Signature: The function receives two arguments: (props, context).

    • props: An object containing the props passed to the component in JSX.

    • context: The global context object you defined, plus a reference to all other registered components. You can destructure other components directly from this object.

Example: views/components/Article.jsx

// This component can be sync or async
// Notice how we destructure 'utils' and 'UserInfo' from the context (the second argument).
export default function Article({ article }, { utils, UserInfo }) {
  return (
    <article className="article-body">
      <h2>{article.title}</h2>
      <p>Published on: {utils.formatDate(article.publishDate)}</p>
      <UserInfo user={article.author} />
    </article>
  );
}

Pages

A Page is simply a Component that also exports a route constant. These are the entry points for incoming requests.

Page components receive the same arguments as regular components, but their context object contains additional request-specific properties:

  • req: The Express request object.

  • res: The Express response object.

  • query: An object containing the URL query parameters.

Page Configuration

You can configure a page's behavior using special named exports within the .jsx file.

route

This required export defines the URL path(s) for the page. It can be a single string or an array of strings. The route will be registered as a GET handler.

// A single route
export const route = '/';

// Multiple routes pointing to the same page
export const route = ['/event/:id', '/data/events/:id'];

params (Data Loading)

This optional export lets you fetch and prepare data before your page component renders. The final result is passed as the props to your page component. There are two powerful strategies for defining params.

Strategy 1: Object-based params

If you export params as an object, each key will become a prop. If a key's value is a function, it will be awaited, and its resolved value will be used.

The functions are resolved sequentially, so a later function can access the value of a previously resolved one.

Example: views/pages/Event.jsx

In this example, notice how the EventPage component destructures the UserInfo component from its context object ({ UserInfo }) and then uses it in the return statement (<UserInfo ... />).

// Define the route for this page
export const route = '/event/:eventId';

// Define data dependencies for the page
export const params = {
  // `eventId` from the route is automatically available
  event: async ({ eventId }, { utils }) => {
    // Fetch event data using a utility from the context
    return await utils.fetchEvent(eventId);
  },
  // This function can use the result of the `event` fetch above
  mainUser: async ({ event }) => {
    return await fetchUser(event.mainContactId);
  }
};

// The page component receives the resolved `event` and `mainUser` as props.
// It also destructures the `UserInfo` component from context to use for rendering.
export default function EventPage({ event, mainUser }, { UserInfo }) {
  return (
    <div>
      <h1>{event.name}</h1>
      <p>Event Contact:</p>
      <UserInfo user={mainUser} />
    </div>
  );
}

Strategy 2: Function-based params

If you export params as a single function, you get full control over the final props object. The function is called with the route parameters and the context, and its return value is merged with the route parameters to become the page's props.

This is useful for more complex data-fetching logic.

export const route = '/event/:eventId';

export const params = async (routeParams, context) => {
  const event = await context.utils.fetchEvent(routeParams.eventId);
  const comments = await context.utils.fetchComments(routeParams.eventId);

  // The returned object becomes the props for the page
  return {
    eventData: event,
    commentList: comments,
    // You can pass functions through as props if needed
    onAction: () => console.log('Action!')
  };
};

export default function EventPage({ eventData, commentList, onAction }) {
  // ... render the page
}