A type-safe, declarative language for defining and documenting URL structures in web applications.
URLSpec is a domain-specific language (DSL) that brings type safety and clarity to URL definitions. Instead of scattering URL structures across your codebase, URLSpec provides a single source of truth for your application's URL architecture.
The Problem: URLs in web applications are typically defined as magic strings scattered throughout the codebase. This leads to:
- Runtime errors from typos or incorrect parameter types
- Difficulty in understanding the complete URL structure of an application
- No type checking for query parameters or path segments
- Hard-to-refactor URL changes across large codebases
The Solution: URLSpec provides a declarative syntax to define your URLs with:
- Type Safety: Catch URL-related errors at development time
- Documentation: Self-documenting URL structures
- IDE Support: Syntax highlighting, validation, and auto-completion
- Code Generation: Generate type-safe URL builders for your application
- Refactorability: Change URLs with confidence
Create a .urlspec file:
namespace "jobs";
param sort_order = "recent" | "popular" | "trending";
param job_status = "active" | "closed" | "draft";
global {
referrer?: "jobs" | "hello";
utm_source?: string;
}
page list = /jobs {
category?: string;
sort: sort_order;
}
page detail = /jobs/:job_id {
job_id: string;
preview?: "true" | "false";
status?: job_status;
}
import { resolve } from '@urlspec/language';
const spec = resolve(urlspecContent);
// Access resolved structure
console.log(spec.namespace); // "jobs"
console.log(spec.pages.list.path); // "/jobs"
console.log(spec.pages.list.parameters.sort.type); // ["recent", "popular", "trending"]import { URLSpec } from '@urlspec/builder';
const spec = new URLSpec();
spec.setNamespace('jobs');
spec.addParamType('sort_order', ['recent', 'popular', 'trending']);
spec.addPage({
name: 'list',
path: '/jobs',
parameters: [
{ name: 'category', type: 'string', optional: true },
{ name: 'sort', type: 'sort_order' },
],
});
console.log(spec.toString());This repository is organized as a monorepo containing three main packages:
| Package | Description | Version |
|---|---|---|
| @urlspec/language | Core language implementation, parser, and resolver | |
| @urlspec/builder | Programmatic API for building URLSpec files | |
| urlspec-vscode-extension | VS Code extension with syntax highlighting and validation | - |
┌─────────────────────────────────────────────────────┐
│ Your Application │
└──────────────┬─────────────────────┬─────────────────┘
│ │
│ │
┌──────▼──────┐ ┌──────▼──────┐
│ @urlspec/ │ │ @urlspec/ │
│ language │◄──────│ builder │
│ │ │ │
│ (Parser & │ │ (Builder │
│ Resolver) │ │ API) │
└──────▲──────┘ └─────────────┘
│
│
┌──────▼──────────────────┐
│ urlspec-vscode- │
│ extension │
│ │
│ (IDE Integration) │
└─────────────────────────┘
URLSpec supports a type system for query parameters:
- String Type:
string - String Literals:
"active","closed" - Union Types:
"recent" | "popular" | "trending" - Type Aliases: Define reusable types with
param
Define paths with static and dynamic segments:
page static = /jobs/list // Static path
page dynamic = /jobs/:job_id // Single param
page nested = /articles/:article_id/comments/:comment_id // Multiple params
Define query parameters that apply to all pages:
global {
utm_source?: string;
utm_campaign?: string;
referrer?: string;
}
- Node.js 24+
- Yarn 4.12.0+
# Install dependencies
yarn install
# Build all packages
yarn build
# Format code
yarn formatyarn build- Build all packages in dependency orderyarn format- Check and fix code formatting with Biome
Each package has its own development scripts:
# Language package
cd packages/language
yarn test # Run tests
yarn test:watch # Watch mode
yarn langium:generate # Generate parser from grammar
# Builder package
cd packages/builder
yarn test # Run tests
yarn test:watch # Watch mode
# VS Code Extension
cd packages/urlspec-vscode-extension
yarn watch # Watch mode for development
yarn build # Build and package extension