
Security News
Axios Supply Chain Attack Reaches OpenAI macOS Signing Pipeline, Forces Certificate Rotation
OpenAI rotated macOS signing certificates after a malicious Axios package reached its CI pipeline in a broader software supply chain attack.
@gamesome/route-builder
Advanced tools
Typesafe, ergonomic javascript route-builder. No framework dependencies or magic string nonsense.
Have you ever been frustrated by not having a good way to manage your application's routes in a type-safe manner? Are you resorting to magic strings scattered throughout your codebase, and constantly breaking prod when your api server tries to redirect to a non-existing route?
@gamesome/route-builder is here to help!
You can now build your application's routes in a type-safe way with support for dynamic segments like so:
import { buildRoutes } from '@gamesome/route-builder';
const routes = buildRoutes({
$: '/',
user: {
$: '/users',
id: (userId: string) => `/${userId}`,
},
});
routes.$; // "/"
routes.user.$; // "/users"
routes.user.id('123'); // "/users/123"
You can also get fancy by creating a branded type like so:
type UserId = string & { __brand: 'UserId' };
const routes = buildRoutes({
user: {
id: (userId: string) => `/${userId as UserId}`,
},
});
routes.user.id('123'); // "/users/${UserId}"
If you need base urls in your routes you can do that as well. You configure this in the second argument to buildRoutes by passing an object with a baseUrl property. If you want both relative and absolute urls you can set inSeparateBranch to true in the same object. Per default the base url will be represented as BaseUrl in typehints, but if you want the actual string you can set fullBaseUrlInTypeHints to true.
const routes = buildRoutes(
{
$: '/',
about: {
$: '/about',
},
},
{
baseUrl: 'https://example.com',
inSeparateBranch: true,
fullBaseUrlInTypeHints: true,
}
);
routes.$; // "/"
routes.about.$; // "/about"
routes.withBaseUrl.$; // "https://example.com/"
routes.withBaseUrl.about.$; // "https://example.com/about"
In your IDE you will see autocompletion for both static and dynamic routes. as well as hints indicating what will be generated.
npm install @gamesome/route-builder
# or
yarn add @gamesome/route-builder
Most tsconfig.json setups work out of the box. If you export routes from a built package with declaration: true, TypeScript will emit fully typed .d.ts files — no extra tooling required. Just make sure your package.json exposes the right entry points (an exports map with types and import conditions, and/or top-level main + types).
isolatedDeclarationsWhen isolatedDeclarations: true is enabled, TypeScript requires every export to carry an explicit type annotation that the declaration emitter can resolve without running the type checker. Because buildRoutes returns a deeply inferred type, tsc will error on the bare export.
as const or a helper function?You might think you can sidestep the generator by extracting the route config into a variable with as const and annotating the export with a type like InferRoutes<typeof config>. This runs into two problems:
as const doesn't narrow function return types. Arrow functions inside the config (dynamic route segments) still need individual explicit return type annotations, which quickly becomes verbose and error-prone for nested routes.defineRoutes() can't be resolved in isolation. isolatedDeclarations requires that types are determinable without cross-file type inference. A function call's return type depends on the function's generic signature in another module, which the declaration emitter can't resolve.Both approaches break down for any non-trivial route map that includes dynamic segments. The generator exists specifically to solve this — it pre-computes the fully resolved type and writes it to a .ts file that the declaration emitter can consume as-is.
For this case the library ships a generator CLI (route-builder-generate) and a companion function (buildRoutesWithGenerator):
import { buildRoutesWithGenerator } from '@gamesome/route-builder/generator';
import type { AppRoutes } from './routes.generated';
export const appRoutes: AppRoutes = buildRoutesWithGenerator({
$: '/',
users: {
$: '/users',
id: (userId: string) => `/${userId}`,
},
});
Then generate the type file as part of your build:
route-builder-generate src/index.ts \
--out src/routes.generated.ts \
--export appRoutes \
--type AppRoutes
src/index.ts — the source file that contains the route definition.--out — where to write the generated type file.--export — the name of the exported variable to read the type from (must match your export const …).--type — the name of the generated type alias (must match the import type { … } in your source).Use a .ts extension for --out (not .d.ts) so that tsc emits the corresponding .d.ts into dist/ automatically.
FAQs
Typesafe, ergonomic javascript route-builder. No framework dependencies or magic string nonsense.
The npm package @gamesome/route-builder receives a total of 9 weekly downloads. As such, @gamesome/route-builder popularity was classified as not popular.
We found that @gamesome/route-builder demonstrated a healthy version release cadence and project activity because the last version was released less than a year ago. It has 1 open source maintainer collaborating on the project.
Did you know?

Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.

Security News
OpenAI rotated macOS signing certificates after a malicious Axios package reached its CI pipeline in a broader software supply chain attack.

Security News
Open source is under attack because of how much value it creates. It has been the foundation of every major software innovation for the last three decades. This is not the time to walk away from it.

Security News
Socket CEO Feross Aboukhadijeh breaks down how North Korea hijacked Axios and what it means for the future of software supply chain security.