[Feature]: File-based routing build plugin for Ripple (Next.js / SolidStart inspired)
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
.ripplefile insrc/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.rippleGenerated manifest:
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:
<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 entrylayout.tsx→ layout wrappererror.tsx/not-found.tsx→ special boundaries
SvelteKit
- SvelteKit Routing Guide
- Uses
+page.svelte,+layout.svelte, and+error.svelteconventions. - 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.tsxand 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
Source: Ripple-TS/ripple