#552·ripple

[Feature]: File-based routing build plugin for Ripple (Next.js / SolidStart inspired)

Author: P4ST4SCreated Nov 10, 2025Updated May 2, 2026
Labelsenhancement

Feature Category

Developer Experience

Problem Statement

Ripple currently lacks a built-in file-based routing system. While the declarative router provides basic navigation, developers must manually define and import routes, which becomes cumbersome as applications grow.

This limitation makes it harder to:

  • Organize large projects intuitively (e.g., one file per route).
  • Leverage features like dynamic routes (/users/:id), layouts, or 404 pages.
  • Integrate SSR or lazy-loading seamlessly later on.

In short, there’s no standardized, scalable convention for routing — which negatively impacts developer experience and project structure consistency.

Proposed Solution

Introduce a file-based routing system through a Vite-compatible build plugin, similar to Next.js and SolidStart conventions. This plugin would scan the src/routes/ directory at build time and generate a typed routeManifest.ts file automatically.

Key points of the design:

  • Automatic route discovery: Each .ripple file in src/routes/ maps directly to a route.
  • Dynamic segments: [id].ripple/users/:id.
  • Lazy loading: Each route is imported dynamically via import().
  • Hot Reload (HMR): The manifest regenerates on file changes.
  • TypeScript-first: The manifest and route helpers are fully typed.

Example:

src/routes/
  _layout.ripple
  index.ripple
  about.ripple
  users/
    [id].ripple
    [id]/_layout.ripple
    [id]/settings.ripple
  _error.ripple
  _not-found.ripple

Generated manifest:

typescript
export const routeManifest = {
  "/": () => import("./routes/index.ripple"),
  "/about": () => import("./routes/about.ripple"),
  "/users/:id": () => import("./routes/users/[id].ripple"),
};

The runtime would consume this manifest automatically:

javascript
<Router manifest={routeManifest} />

This approach keeps Ripple lightweight while providing a modern DX, laying the foundation for future features such as:

  • Nested layouts via _layout.ripple
  • Global error boundaries (_error.ripple)
  • Prefetching and SSR integration

Alternatives Considered

We could keep the current declarative router only, but it doesn’t scale for large apps.

Examples & References

This proposal draws inspiration from several mature frameworks that successfully implement file-based routing with great developer experience:

Next.js

  • Next.js Routing Documentation
  • Uses the filesystem as the main API for routes (/app directory).
  • Supports nested layouts, error boundaries, and dynamic segments.
  • Convention examples:
  • page.tsx → route entry
  • layout.tsx → layout wrapper
  • error.tsx / not-found.tsx → special boundaries

SvelteKit

  • SvelteKit Routing Guide
  • Uses +page.svelte, +layout.svelte, and +error.svelte conventions.
  • Supports automatic parameterized routes ([id].svelte) and route grouping.
  • Provides great DX through hot-reload and prefetching mechanisms.

SolidStart

  • SolidStart File-based Routing
  • Introduces _layout.tsx and dynamic [param] conventions.
  • Lightweight, simple, and compatible with Vite — similar goals to Ripple.
  • Ideal reference for implementing a minimal TypeScript-first router.

Astro

  • Astro Routing Docs
  • Also uses file-based routes, combining static and dynamic behavior.
  • Good example of hybrid support (SSG + SSR).

Checklist

  • I've searched for existing feature requests
  • I'm willing to help implement this feature