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 🙏

© 2025 – Pkg Stats / Ryan Hefner

@zomme/bun-plugin-tsr

v0.1.1

Published

Bun plugin for TanStack Router route generation with file-based routing

Readme

@zomme/bun-plugin-tsr

Bun plugin for TanStack Router route generation with file-based routing.

Features

  • Automatic route tree generation from file structure
  • Watch mode for development (auto-regenerates on file changes)
  • Configurable via bunfig.toml
  • Supports multiple root directories
  • Full TypeScript support

Installation

bun add -d @zomme/bun-plugin-tsr

Install peer dependencies:

bun add @tanstack/react-router
bun add -d @tanstack/router-generator

Usage

Basic Setup

Add the plugin to your bunfig.toml:

[serve.static]
plugins = ["@zomme/bun-plugin-tsr"]

Or use it programmatically:

import tsr from "@zomme/bun-plugin-tsr";

Bun.build({
  entrypoints: ["./src/index.tsx"],
  plugins: [tsr],
});

Configuration

Configure via bunfig.toml:

[plugins.tsr]
rootDirectory = "src"
routesDirectory = "./routes"
generatedRouteTree = "routeTree.gen.ts"
quoteStyle = "double"
routeFileIgnorePattern = ".test."

Configuration Options

| Option | Type | Default | Description | |--------|------|---------|-------------| | rootDirectory | string \| string[] | "src" | Root directory for routes | | routesDirectory | string | "./routes" | Routes directory relative to root | | generatedRouteTree | string | "routeTree.gen.ts" | Output file name | | quoteStyle | "single" \| "double" | "double" | Quote style in generated code | | routeFileIgnorePattern | string | ".test." | Pattern to ignore route files |

Directory Structure

Create routes using file-based routing:

src/
├── routes/
│   ├── __root.tsx         # Root layout
│   ├── index.tsx          # / (home page)
│   ├── about.tsx          # /about
│   ├── dashboard/
│   │   ├── index.tsx      # /dashboard
│   │   ├── settings.tsx   # /dashboard/settings
│   │   └── $userId.tsx    # /dashboard/:userId (dynamic)
│   └── posts/
│       ├── index.tsx      # /posts
│       └── $postId.tsx    # /posts/:postId (dynamic)
├── routeTree.gen.ts       # Generated route tree (auto)
└── main.tsx

Route File Naming Conventions

| File Name | Route Path | Description | |-----------|------------|-------------| | index.tsx | / | Index route | | about.tsx | /about | Static route | | $userId.tsx | /:userId | Dynamic parameter | | posts.$postId.tsx | /posts/:postId | Nested dynamic | | __root.tsx | - | Root layout | | -components/ | - | Private folder (ignored) |

Example

Root Layout

// src/routes/__root.tsx
import { Outlet, createRootRoute } from "@tanstack/react-router";

export const Route = createRootRoute({
  component: RootComponent,
});

function RootComponent() {
  return (
    <div>
      <nav>
        <Link to="/">Home</Link>
        <Link to="/about">About</Link>
        <Link to="/dashboard">Dashboard</Link>
      </nav>
      <main>
        <Outlet />
      </main>
    </div>
  );
}

Index Route

// src/routes/index.tsx
import { createFileRoute } from "@tanstack/react-router";

export const Route = createFileRoute("/")({
  component: HomePage,
});

function HomePage() {
  return <h1>Welcome Home</h1>;
}

Dynamic Route

// src/routes/posts/$postId.tsx
import { createFileRoute } from "@tanstack/react-router";

export const Route = createFileRoute("/posts/$postId")({
  component: PostPage,
  loader: async ({ params }) => {
    const post = await fetchPost(params.postId);
    return { post };
  },
});

function PostPage() {
  const { post } = Route.useLoaderData();
  return <article>{post.title}</article>;
}

App Entry Point

// src/main.tsx
import { RouterProvider, createRouter } from "@tanstack/react-router";
import { routeTree } from "./routeTree.gen";

const router = createRouter({ routeTree });

declare module "@tanstack/react-router" {
  interface Register {
    router: typeof router;
  }
}

function App() {
  return <RouterProvider router={router} />;
}

Watch Mode

In development (NODE_ENV !== "production"), the plugin automatically watches for file changes:

  • Create: New route files are detected and added
  • Update: Modified routes trigger regeneration
  • Delete: Removed files are cleaned from route tree
# Development - watch mode enabled
bun dev

# Production - no watch mode
NODE_ENV=production bun build

Multiple Root Directories

Support multiple entry points:

[plugins.tsr]
rootDirectory = ["apps/web/src", "apps/admin/src"]

Generated Route Tree

The plugin generates a routeTree.gen.ts file:

// This file is auto-generated by @zomme/bun-plugin-tsr

import { Route as rootRoute } from "./routes/__root";
import { Route as IndexRoute } from "./routes/index";
import { Route as AboutRoute } from "./routes/about";
import { Route as DashboardIndexRoute } from "./routes/dashboard/index";

const routeTree = rootRoute.addChildren([
  IndexRoute,
  AboutRoute,
  DashboardIndexRoute,
]);

export { routeTree };

How It Works

  1. Scan: Plugin scans routesDirectory for route files
  2. Parse: Analyzes file names for route patterns
  3. Generate: Creates route tree with proper nesting
  4. Watch: In dev mode, watches for changes and regenerates

Requirements

  • Bun >= 1.0.0
  • @tanstack/react-router >= 1.0.0
  • @tanstack/router-generator >= 1.0.0

License

MIT