diff --git a/CHANGELOG.md b/CHANGELOG.md
index ee05d73..e2e7cb1 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,122 +1,191 @@
# Changelog
-## 13 -> 15.0.0
+All notable changes to XRoute will be documented in this file.
-- Added feature: `useOptimizedObservability` option to router
- - By default is true
- - Optimized `search` and `pathname` on routes to only update deep properties on change
- - This should improve render performance!
-- Added feature: `XRoute('someRoute').Schema({ ... })` to define a schema for a route
- - This accepts zod schemas to define the `pathname` and `search` and `hash`
- - For the time being, no schema validation is run, it is only for types
- - However, one can access the schema to validate with it manually eg. `route.schema.schema.pathname.parse(route.pathname)`
+The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
+and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
-## 12.0.0
+## [15.0.0] - 2024-XX-XX
-- Write better inline JSDOC comments for methods
-- Remove unused config option
-
-## 11.0.0
+### ๐ Added
+- **Performance Optimization**: `useOptimizedObservability` option for router (enabled by default)
+ - Optimizes `search` and `pathname` updates to only trigger on actual property changes
+ - Significantly improves render performance in complex applications
+- **Schema Support**: `XRoute('routeName').Schema({ ... })` method for Zod schema integration
+ - Accepts Zod schemas for `pathname`, `search`, and `hash` parameters
+ - Currently provides type-only validation (runtime validation planned)
+ - Manual validation available via `route.schema.schema.pathname.parse(route.pathname)`
-- Refined refactor from 10.0.0-0
-- Tested
+### ๐ Documentation
+- Complete documentation restructure with improved organization
+- Added comprehensive API reference
+- Added quick start guide with step-by-step instructions
+- Added troubleshooting guide and migration documentation
-## 10.0.0-0
+## [12.0.0] - 2024-XX-XX
-Rewrite of core to optimize for performance and reduce observable overhead.
+### ๐ง Improved
+- Enhanced inline JSDoc comments for better IDE support
+- Removed unused configuration options for cleaner API
-Any deprecated methods have been annotated with alternative usages.
+### ๐งน Maintenance
+- Code cleanup and optimization
+## [11.0.0] - 2024-XX-XX
-## 6.1.0
+### ๐ง Improved
+- Refined refactor from 10.0.0-0 with stability improvements
+- Comprehensive testing and bug fixes
-- Add missing `qs` dependency
-- Remove unecessary deps
+### โ
Testing
+- Enhanced test coverage for core functionality
-### Internal
+## [10.0.0] - 2024-XX-XX
-- Using `pnpm` instead of `yarn`
-- Using `vite` instead of `snowpack`
+### โก Performance
+- **BREAKING**: Major rewrite of core architecture for performance optimization
+- Reduced observable overhead for better memory usage
+- Optimized route matching and parameter parsing
-## 6.0.1
+### ๐ Migration
+- Deprecated methods have been annotated with alternative usage patterns
+- See [Migration Guide](./docs/Migration.md) for detailed upgrade instructions
-- Allow for search params to inherit shallow props when changing within the same route.
- - > Note: Switching between different routes will still NOT preserve properties in `search`.
- - Old behaviour:
- ```ts
- router.routes.a.push({ search: { a: 1 } })
- // /a/?a=1
- router.routes.a.push({ search: { b: 2 } })
- // /a/?b=1
- ```
- - New behaviour:
- ```ts
- router.routes.a.push({ search: { a: 1 } })
- // /a/?a=1
- router.routes.a.push({ search: { b: 2 } })
- // /a/?a=1&b=1
+## [6.1.0] - 2023-XX-XX
- // Moving to a new route will NOT keep old variables - this would be too confusing to keep track of
- router.routes.b.push({ search: { z: 1 } })
- // /b/?z=1
- ```
- - Remember, you can use `.pushExact({ search: { } })` to ignore old properties.
+### ๐ง Fixed
+- Added missing `qs` dependency to package.json
+- Removed unnecessary dependencies for smaller bundle size
-## 5.4.0
+### ๐ ๏ธ Internal
+- Migrated from `yarn` to `pnpm` for package management
+- Migrated from `snowpack` to `vite` for build tooling
-- Ensure search & hash location params get reset while iteracting with `history` via workaround
- - https://github.com/ReactTraining/history/issues/811
-- Can now switch between routes and have the `search` and `hash` reset properly
+## [6.0.1] - 2023-XX-XX
-## 5.3.1
+### ๐ Added
+- **Search Parameter Inheritance**: Search params now inherit shallow properties when navigating within the same route
-- Remove a console.log statement
-
-## 5.3.0
+### ๐ Behavior Changes
+- **Previous Behavior**:
+ ```typescript
+ router.routes.a.push({ search: { a: 1 } }) // /a/?a=1
+ router.routes.a.push({ search: { b: 2 } }) // /a/?b=2 (lost 'a')
+ ```
+- **New Behavior**:
+ ```typescript
+ router.routes.a.push({ search: { a: 1 } }) // /a/?a=1
+ router.routes.a.push({ search: { b: 2 } }) // /a/?a=1&b=2 (preserved 'a')
-- Correctly rename `toPathExact` to `toUriExact` as it should be for v5
-
-## 5.2.0
+ // Cross-route navigation still resets parameters
+ router.routes.b.push({ search: { z: 1 } }) // /b/?z=1 (no inheritance)
+ ```
-- Fixes types for active route helper functions
+### ๐ก Usage Notes
+- Use `.pushExact({ search: { } })` to ignore inherited properties when needed
+- Parameter inheritance only applies within the same route
-## 5.1.0
+## [5.4.0] - 2023-XX-XX
-- Added `search` querystring support
+### ๐ง Fixed
+- **History Integration**: Fixed search & hash parameter reset issues
+ - Implemented workaround for [History library issue #811](https://github.com/ReactTraining/history/issues/811)
+ - Route switching now properly resets `search` and `hash` parameters
-### Breaking
-- `toPath` renamed to `toUri`
-- Pathname parameters are now set differently:
- - โ Old: `router.routes.myRoute.push({ myVar: 2 })`
- - โ
New: `router.routes.myRoute.push({ pathname: { myVar: 2 } })`
-- Pathname params now accessable from `router.routes.myRoute.pathname?.myVar`
+### โ
Improved
+- Enhanced route transition reliability
-## 4.0.0
+## [5.3.1] - 2023-XX-XX
-- Add `mjs` modules from `./dist/es/`
-
-## 3.1.0
+### ๐งน Maintenance
+- Removed debug console.log statement
-- Make `findActiveRoute` and other utilities allow for undefined items
-
-## 3.0.0
+## [5.3.0] - 2023-XX-XX
-- Added `toPath`, which generates a pathname.
- - `xrouter.routes.myRoute.toPath({ someParam: 'foo' }) // "/blahblah/foo"`
- - `xrouter.toPath(MyFancyRoute, { someParam: 'foo' }) // "/blahblah/foo"`
+### ๐ง Fixed
+- Correctly renamed `toPathExact` to `toUriExact` for consistency with v5 API
-## 2.0.0
+## [5.2.0] - 2023-XX-XX
-- Includes breaking changes from 1.6.0
+### ๐ง Fixed
+- Fixed TypeScript types for active route helper functions
-## 1.6.0
+## [5.1.0] - 2023-XX-XX
-- Added `router.routes.myRoute.pushExact` and `router.routes.myRoute.replaceExact`
- - These methods will only use the provided parameters
-- Changed `routes.myRoute.push` and `routes.myRoute.replace`
- - These methods will now spread the currently active params in for you so you can apply a partial update
-- Published as minor by accent - see v2.0.0
+### ๐ Added
+- **Search Parameter Support**: Full querystring parameter support with type safety
-## 1.5.0
+### ๐ฅ BREAKING CHANGES
+- **Method Rename**: `toPath` โ `toUri`
+- **Parameter Structure**: Changed pathname parameter API
+ ```typescript
+ // โ Old API
+ router.routes.myRoute.push({ myVar: 2 })
-...
\ No newline at end of file
+ // โ
New API
+ router.routes.myRoute.push({ pathname: { myVar: 2 } })
+ ```
+- **Parameter Access**: Updated parameter access pattern
+ ```typescript
+ // Access pathname parameters
+ router.routes.myRoute.pathname?.myVar
+ ```
+
+## [4.0.0] - 2022-XX-XX
+
+### ๐ Added
+- **ES Modules**: Added `mjs` modules in `./dist/es/` for better tree-shaking
+
+## [3.1.0] - 2022-XX-XX
+
+### ๐ง Improved
+- Enhanced `findActiveRoute` and utility functions to handle undefined values gracefully
+
+## [3.0.0] - 2022-XX-XX
+
+### ๐ Added
+- **URL Generation**: New `toPath` method for generating pathnames
+ ```typescript
+ // Generate URL from route and parameters
+ xrouter.routes.myRoute.toPath({ someParam: 'foo' }) // "/blahblah/foo"
+ xrouter.toPath(MyFancyRoute, { someParam: 'foo' }) // "/blahblah/foo"
+ ```
+
+## [2.0.0] - 2022-XX-XX
+
+### ๐ฅ BREAKING CHANGES
+- Includes all breaking changes from v1.6.0 (see below)
+
+## [1.6.0] - 2022-XX-XX
+
+### ๐ Added
+- **Exact Navigation Methods**:
+ - `router.routes.myRoute.pushExact` - Uses only provided parameters
+ - `router.routes.myRoute.replaceExact` - Uses only provided parameters
+
+### ๐ Changed
+- **Parameter Merging**: `push` and `replace` methods now merge with current parameters
+ - Enables partial parameter updates
+ - Use `pushExact`/`replaceExact` for previous behavior
+
+### โ ๏ธ Note
+- Originally published as minor version, promoted to major in v2.0.0
+
+## [1.5.0] - 2022-XX-XX
+
+### ๐ Legacy Features
+- Initial feature set and API establishment
+
+---
+
+## Migration Guides
+
+- **v15.x**: See [Migration Guide](./docs/Migration.md) for detailed upgrade instructions
+- **v10.x+**: Major performance improvements with some API changes
+- **v5.x+**: Search parameter support with breaking parameter API changes
+
+## Support
+
+- ๐ [Documentation](./docs/)
+- ๐ [Report Issues](https://github.com/nfour/xroute/issues)
+- ๐ฌ [Discussions](https://github.com/nfour/xroute/discussions)
\ No newline at end of file
diff --git a/README.md b/README.md
index defc14a..72d919c 100644
--- a/README.md
+++ b/README.md
@@ -1,317 +1,215 @@
# XRoute
-Mobx powered `History` router, with types.
-
-+ [Features](#features)
-+ [Usage](#usage)
-+ [Troubleshooting](#troubleshooting)
- + [Typescript errors](#typescript-errors)
-
-
-## Features
-
-- [x] Declarative observable wrapper over the `History` interface
-- [x] Type safe `pathname` params
-- [x] Type safe `search` params via `qs` serialization
-- [x] Type safe `hash` string
-- [x] Workarounds for some known issues with History: [Here](https://github.com/ReactTraining/history/issues/811)
-- [x] Route inheritance for nesting routes
-
-
-
-## Usage
+A type-safe, MobX-powered router for React applications with declarative route definitions and observable navigation state.
+
+## Table of Contents
+
+- [Overview](#overview)
+- [Installation](#installation)
+- [Quick Start](#quick-start)
+- [Core Concepts](#core-concepts)
+- [Documentation](#documentation)
+- [Examples](#examples)
+- [What's New](#whats-new)
+- [Requirements](#requirements)
+- [Contributing](#contributing)
+
+## Overview
+
+XRoute provides a modern, type-safe routing solution that integrates seamlessly with MobX and React. It offers:
+
+- **Type Safety**: Full TypeScript support for pathname, search, and hash parameters
+- **MobX Integration**: Observable router state with automatic re-rendering
+- **Declarative Routes**: Clean, composable route definitions
+- **Route Inheritance**: Nested routes with parameter inheritance
+- **History Integration**: Built on the standard `history` library
+- **Performance Optimized**: Efficient observable updates and render optimization
+
+## Installation
+
+```bash
+npm install xroute history mobx zod
+# or
+yarn add xroute history mobx zod
+# or
+pnpm add xroute history mobx zod
+```
-- [x] Requires >= Mobx@6
+### Peer Dependencies
-> See the [stories for usage examples](./stories/mobx.stories.tsx)
+- `history` ^5.0.0
+- `mobx` ^6.0.0
+- `zod` ^3.0.0
-- [docs/routeDefinition.ts](./docs/routeDefinition.ts)
+## Quick Start
-
+### 1. Define Your Routes
-```tsx
-import { createBrowserHistory } from 'history'
-import { XRoute, XRouter } from 'xroute'
+```typescript
+import { XRoute } from 'xroute'
-/** A simple route, matches the `/`, the root page */
-export const HomeRoute = XRoute('home')
- .Resource('/') // /
+// Simple route with no parameters
+const HomeRoute = XRoute('home')
+ .Resource('/')
.Type<{
pathname: {}
search: {}
}>()
-export const AdminRoute = XRoute('admin')
- .Resource(
- `/admin`, // /admin
- )
+// Route with parameters
+const UserRoute = XRoute('user')
+ .Resource('/user/:userId')
.Type<{
- pathname: {}
- search: { isAdvancedView?: boolean }
+ pathname: { userId: string }
+ search: { tab?: 'profile' | 'settings' }
}>()
+```
-enum AdminAnalyticsSubSections {
- TopPages = 'topPages',
- TopUsers = 'topUsers',
- RawData = 'rawData',
-}
-
-const AdminAnalyticsSubsectionsURI = `:subSection(${AdminAnalyticsSubSections.TopPages}|${AdminAnalyticsSubSections.TopUsers}|${AdminAnalyticsSubSections.RawData})?`
-
-//
-// OR:
-// if you dont care about type safety, do this:
-//
-
-const AdminAnalyticsSubsectionsURILoose = `:subSection(${Object.values(
- AdminAnalyticsSubSections,
-).join('|')})?` as const
+### 2. Create a Router
-export const AdminAnalyticsRoute = AdminRoute.Extend('adminAnalytics')
- .Resource(`/analytics/${AdminAnalyticsSubsectionsURI}`) // /admin/analytics/:subSection(topPages|topUsers|rawData)
- .Type<{
- pathname: { subSection?: AdminAnalyticsSubSections }
- search: {}
- }>()
+```typescript
+import { createBrowserHistory } from 'history'
+import { XRouter } from 'xroute'
-export const AdminUsersRoute = AdminRoute.Extend('adminUsers')
- .Resource(`/users`) // /admin/users
- .Type<{
- pathname: {}
+const router = new XRouter(
+ [UserRoute, HomeRoute], // Order matters - first match wins
+ createBrowserHistory()
+)
+```
- // You don't need to use the pathname at all if you want to keep it simple
- // Can even nest objects and arrays.
- search: {
- userId?: string // ends up as ?userId=123
- editor?: {
- line?: string
- activeToolId?: string
- selectedItems?: string[]
- } // ?editor[line]=1&editor[activeToolId]=2&editor[selectedItems]=3&editor[selectedItems]=4
- }
- }>()
+### 3. Navigate Programmatically
-export const NotFoundRoute = XRoute('notFound')
- .Resource('/:someGarbage(.*)?') // /:someGarbage(.*)?
- .Type<{
- pathname: {
- /** The pathname that didnt match any route */
- someGarbage?: string
- }
- search: {}
- }>()
+```typescript
+// Navigate to home
+router.routes.home.push({})
-export function createRouter() {
- return new XRouter(
- // Order matters, notice the `notFound` route is at the end, to act as a fallback
- [
- AdminAnalyticsRoute, // /admin/analytics/topPages
- AdminUsersRoute, // /admin/users?userId=123&editor[line]=1&editor[activeToolId]=2&editor[selectedItems]=3&editor[selectedItems]=4
- AdminRoute, // /admin
- HomeRoute, // /
- NotFoundRoute, // /asdaskjdkalsdjklasd
- ],
- createBrowserHistory(),
- )
-}
+// Navigate to user profile
+router.routes.user.push({
+ pathname: { userId: '123' },
+ search: { tab: 'profile' }
+})
+// Get current route information
+console.log(router.route?.key) // 'user'
+console.log(router.routes.user.pathname?.userId) // '123'
```
-- [docs/fullExample.tsx](./docs/fullExample.tsx)
+### 4. React Integration
```tsx
-import { createHashHistory } from 'history'
-import { autorun, makeAutoObservable, reaction } from 'mobx'
import { observer } from 'mobx-react-lite'
-import * as React from 'react'
-import { XRoute, XRouter } from 'xroute'
-
-//
-// Define some routes
-//
-const HomeRoute = XRoute('home')
- .Resource('/') // Optional language param, eg. /en or /
- .Type<{
- pathname: {}
- search: { language?: 'en' | 'da' | 'de' }
- }>()
-
-const UserProfileRoute = HomeRoute.Extend('userProfile')
- .Resource('/user/:userId') // Required language, eg. /da/user/11
- .Type<{
- pathname: { userId: string }
- search: { profileSection: 'profile' | 'preferences' }
- }>()
-
-const router = new XRouter([UserProfileRoute, HomeRoute], createHashHistory())
-
-export type MyXRouter = typeof router
-
-// Log some changes
-autorun(() => console.log('Active route:', router.route))
-
-// Navigate to: /?language=en
-router.routes.home.push({ pathname: { language: 'en' } })
-
-// Get the pathname, eg. to put inside an
-const homeDaUri = router.routes.home.toUri({ pathname: { language: 'da' } }) // "/da"
-
-// Navigates to: /user/11?language=en
-router.routes.userProfile.push({
- pathname: { userId: '11' },
- search: { language: 'en' },
-})
-
-// Just change the language in the active route.
-// This works as long as the parameter is shared between all routes.
-// Navigates to: /user/11?language=da
-router.route?.push({ pathname: { language: 'da' } })
-
-// Re-use the current language
-// Navigates to: /?language=da
-router.routes.home.push({
- search: { language: router.route?.search.language },
+const App = observer(() => {
+ return (
+
+ {router.route?.key === 'home' && }
+ {router.route?.key === 'user' && }
+
+ )
})
+```
-// Provide a route object to route from anywhere:
-// Navigate to: /de/user/55
-router.push(UserProfileRoute, {
- pathname: { userId: '55' },
- search: { language: 'de' },
-})
+## Core Concepts
-// Read route properties:
+### Route Definition
+Routes are defined using the fluent API with `.Resource()` for URL patterns and `.Type<>()` for TypeScript types.
-/** This must be read from the `routes.userProfile` for the type to be consistent */
-router.routes.userProfile.pathname?.userId // => '55'
+### Route Inheritance
+Use `.Extend()` to create nested routes that inherit parent parameters and paths.
-/** Because `language` is available on all routes, we can read it from the active route at `router.route` */
-router.route?.search?.language
+### Observable State
+Router state is fully observable - components automatically re-render when routes change.
-class UserProfilePage {
- constructor(private router: MyXRouter) {
- this.router = router
+### Type Safety
+All route parameters are type-checked at compile time, preventing runtime errors.
- makeAutoObservable(this)
- }
+## Documentation
- get route() {
- return this.router.routes.userProfile
- }
+- **[Quick Start Guide](./docs/QuickStart.md)** - Step-by-step tutorial
+- **[API Reference](./docs/API.md)** - Complete API documentation
+- **[Examples](./docs/Examples.md)** - Common patterns and use cases
+- **[Troubleshooting](./docs/Troubleshooting.md)** - Common issues and solutions
+- **[Migration Guide](./docs/Migration.md)** - Upgrading between versions
- get userId() {
- return this.route.pathname?.userId
- }
+### Convention Guides
+- **[TypeScript Conventions](./docs/conventions/TypeScript.md)** - Type safety patterns
+- **[React Conventions](./docs/conventions/React.md)** - Component integration patterns
+- **[MobX Conventions](./docs/conventions/MobX.md)** - Observable state patterns
- get profileSection() {
- return this.route.search?.profileSection
- }
+## Examples
- setUserId(userId: string) {
- // Uses current route params
- this.route.push({ pathname: { userId } })
+### Basic Route Definition
+See [docs/routeDefinition.ts](./docs/routeDefinition.ts) for comprehensive route examples.
- //
- // or
- //
- // Explicitly use previous params...
- this.route.pushExact((uri) => ({
- ...uri,
- pathname: { ...uri.pathname, userId },
- }))
- }
+### Complete React Application
+See [docs/fullExample.tsx](./docs/fullExample.tsx) for a full React/MobX integration example.
- setProfileSection(profileSection: this['profileSection']) {
- this.route.push({ search: { profileSection } }) // sets ?profileSection=""
- }
-}
+### Interactive Examples
+Explore the [Storybook examples](./stories/mobx.stories.tsx) for interactive demonstrations.
-// Play around with user profile:
-void (async () => {
- const userProfilePage = new UserProfilePage(router)
+## What's New
- userProfilePage.userId // 55
+### Version 15.0.0
+- **Performance**: Added `useOptimizedObservability` for better render performance
+- **Schema Support**: Zod schema integration for route validation
+- **Type Safety**: Enhanced TypeScript support and error messages
- userProfilePage.setUserId('200')
+See the [CHANGELOG.md](./CHANGELOG.md) for complete version history.
- await new Promise((r) => setTimeout(r, 50)) // Give it time to update the URL and come back...
+## Requirements
- userProfilePage.userId // 200
-})()
+- **Node.js**: >= 16.0.0
+- **TypeScript**: >= 4.5.0 (recommended >= 5.0.0)
+- **React**: >= 16.8.0 (for hooks support)
+- **MobX**: >= 6.0.0
-const Component = observer(() => {
- const [router] = React.useState(
- () => new XRouter([UserProfileRoute, HomeRoute], createHashHistory()),
- )
+### Browser Support
+- Modern browsers with ES2020 support
+- IE11+ with polyfills
- return (
- <>
-
- {router.route?.key === 'home' && Home Page!
}
- {
- // Or do this:
- }
- {router.routes.userProfile.isActive && (
-
- User Profile! UserID: {router.routes.userProfile.pathname?.userId}
-
- )}
- >
- )
-})
-
-const listenToUserProfileRoute = () => {
- let previousIsActive: boolean
+## Contributing
- reaction(
- () => router.routes.userProfile.isActive,
- (isActive) => {
- if (isActive === previousIsActive) return // Ignore same state
+We welcome contributions! Please see our contributing guidelines:
- previousIsActive = isActive
+1. **Issues**: Report bugs or request features via GitHub Issues
+2. **Pull Requests**: Follow our PR template and ensure tests pass
+3. **Documentation**: Help improve these docs by submitting PRs
+4. **Examples**: Share your XRoute patterns and use cases
- if (isActive) {
- // on enter route
- // ...
- } else {
- // on exit route
- // ...
- }
- },
- )
-}
+### Development Setup
-```
+```bash
+# Clone the repository
+git clone https://github.com/nfour/xroute.git
+cd xroute
-## Troubleshooting
+# Install dependencies
+pnpm install
-### Typescript errors
+# Run development server
+pnpm dev
-Are you getting an error like this?
+# Run tests
+pnpm test
+# Build the library
+pnpm build
```
-The inferred type of "X" cannot be named without a reference to "Y"
-```
-
-This can be an issue now that the project uses `zod` for schema generation support.
-It can help to update your tsconfig.json with this:
+### Project Structure
+- `src/` - Source code
+- `docs/` - Documentation and examples
+- `stories/` - Storybook examples
+- `x/` - Built output (CJS and ESM)
-```json
-{
- "compilerOptions": {
- "moduleResolution": "NodeNext",
- "module": "NodeNext",
- }
-}
+## License
-```
+MIT License - see [LICENSE](./LICENSE) for details.
-Or if that doesnt work, add one of these imports anywhere in your project
+---
-```ts
-import 'xroute/XRouteSchema'
-// or if that doesnt work in your older typescript project, use the ugly path:
-import 'xroute/x/esm/XRouteSchema'
-```
\ No newline at end of file
+**Need Help?**
+- ๐ [Documentation](./docs/)
+- ๐ [Report Issues](https://github.com/nfour/xroute/issues)
+- ๐ฌ [Discussions](https://github.com/nfour/xroute/discussions)
+- ๐ [Examples](./docs/Examples.md)
\ No newline at end of file
diff --git a/docs/API.md b/docs/API.md
new file mode 100644
index 0000000..4e8348d
--- /dev/null
+++ b/docs/API.md
@@ -0,0 +1,457 @@
+# XRoute API Reference
+
+Complete API documentation for XRoute classes, methods, and types.
+
+## Table of Contents
+
+- [XRoute Class](#xroute-class)
+- [XRouter Class](#xrouter-class)
+- [Route Instance Methods](#route-instance-methods)
+- [Type Definitions](#type-definitions)
+- [Configuration Options](#configuration-options)
+- [Utility Functions](#utility-functions)
+
+## XRoute Class
+
+The `XRoute` class is used to define individual routes with their URL patterns and type information.
+
+### Constructor
+
+```typescript
+XRoute(key: TKey): XRouteBuilder
+```
+
+Creates a new route builder with the specified key.
+
+**Parameters:**
+- `key`: Unique string identifier for the route
+
+**Returns:** XRouteBuilder instance for method chaining
+
+**Example:**
+```typescript
+const HomeRoute = XRoute('home')
+```
+
+### XRouteBuilder Methods
+
+#### `.Resource(pattern: string)`
+
+Defines the URL pattern for the route.
+
+**Parameters:**
+- `pattern`: URL pattern string (supports path-to-regexp syntax)
+
+**Supported Pattern Features:**
+- Static segments: `/users`
+- Parameters: `/users/:userId`
+- Optional parameters: `/users/:userId?`
+- Wildcards: `/files/*`
+- Regex constraints: `/users/:id(\\d+)`
+
+**Example:**
+```typescript
+const UserRoute = XRoute('user')
+ .Resource('/users/:userId')
+```
+
+#### `.Type()`
+
+Defines TypeScript types for route parameters.
+
+**Type Parameters:**
+- `TRouteType`: Object with `pathname`, `search`, and optional `hash` properties
+
+**Example:**
+```typescript
+const UserRoute = XRoute('user')
+ .Resource('/users/:userId')
+ .Type<{
+ pathname: { userId: string }
+ search: { tab?: 'profile' | 'settings' }
+ hash?: 'section1' | 'section2'
+ }>()
+```
+
+#### `.Extend(key: string)`
+
+Creates a child route that inherits from the current route.
+
+**Parameters:**
+- `key`: Unique identifier for the child route
+
+**Returns:** New XRouteBuilder for the child route
+
+**Example:**
+```typescript
+const AdminRoute = XRoute('admin').Resource('/admin')
+const AdminUsersRoute = AdminRoute.Extend('adminUsers')
+ .Resource('/users') // Results in /admin/users
+```
+
+#### `.Schema(schema: ZodSchema)`
+
+Defines Zod schema for runtime validation (optional).
+
+**Parameters:**
+- `schema`: Zod schema object with `pathname`, `search`, and `hash` properties
+
+**Example:**
+```typescript
+import { z } from 'zod'
+
+const UserRoute = XRoute('user')
+ .Resource('/users/:userId')
+ .Schema({
+ pathname: z.object({ userId: z.string() }),
+ search: z.object({ tab: z.enum(['profile', 'settings']).optional() })
+ })
+```
+
+## XRouter Class
+
+The `XRouter` class manages route matching, navigation, and observable state.
+
+### Constructor
+
+```typescript
+new XRouter(
+ routes: TRoutes,
+ history: History,
+ options?: XRouterOptions
+)
+```
+
+**Parameters:**
+- `routes`: Array of route definitions
+- `history`: History instance from the `history` library
+- `options`: Optional configuration object
+
+**Example:**
+```typescript
+import { createBrowserHistory } from 'history'
+
+const router = new XRouter(
+ [UserRoute, HomeRoute],
+ createBrowserHistory(),
+ { useOptimizedObservability: true }
+)
+```
+
+### Properties
+
+#### `router.route`
+
+```typescript
+readonly route: ActiveRoute | null
+```
+
+The currently active route, or `null` if no route matches.
+
+**Properties of ActiveRoute:**
+- `key`: Route identifier
+- `pathname`: Parsed pathname parameters
+- `search`: Parsed search parameters
+- `hash`: Current hash value
+
+#### `router.routes`
+
+```typescript
+readonly routes: RouteInstances
+```
+
+Object containing route instances keyed by route names.
+
+**Example:**
+```typescript
+router.routes.user.push({ pathname: { userId: '123' } })
+```
+
+#### `router.location`
+
+```typescript
+readonly location: Location
+```
+
+Current browser location object from the History API.
+
+#### `router.history`
+
+```typescript
+readonly history: History
+```
+
+The underlying History instance.
+
+### Methods
+
+#### `router.push(route, params)`
+
+Navigate to a specific route.
+
+**Parameters:**
+- `route`: Route definition
+- `params`: Route parameters object
+
+**Example:**
+```typescript
+router.push(UserRoute, {
+ pathname: { userId: '123' },
+ search: { tab: 'profile' }
+})
+```
+
+#### `router.replace(route, params)`
+
+Replace current route without adding history entry.
+
+**Parameters:**
+- `route`: Route definition
+- `params`: Route parameters object
+
+#### `router.back()`
+
+Navigate back in history.
+
+#### `router.forward()`
+
+Navigate forward in history.
+
+#### `router.go(delta: number)`
+
+Navigate to a specific point in history.
+
+**Parameters:**
+- `delta`: Number of steps to move (negative for back, positive for forward)
+
+## Route Instance Methods
+
+Each route in `router.routes` has the following methods:
+
+### Navigation Methods
+
+#### `route.push(params)`
+
+Navigate to this route, merging with current parameters.
+
+```typescript
+router.routes.user.push({
+ pathname: { userId: '456' },
+ search: { tab: 'settings' }
+})
+```
+
+#### `route.replace(params)`
+
+Replace current route with this route.
+
+#### `route.pushExact(params | callback)`
+
+Navigate using exact parameters (no merging).
+
+```typescript
+// With object
+router.routes.user.pushExact({
+ pathname: { userId: '789' },
+ search: { tab: 'profile' }
+})
+
+// With callback
+router.routes.user.pushExact((current) => ({
+ ...current,
+ search: { tab: 'settings' }
+}))
+```
+
+### State Properties
+
+#### `route.isActive`
+
+```typescript
+readonly isActive: boolean
+```
+
+Whether this route is currently active.
+
+#### `route.pathname`
+
+```typescript
+readonly pathname: PathnameType | null
+```
+
+Current pathname parameters for this route (null if not active).
+
+#### `route.search`
+
+```typescript
+readonly search: SearchType | null
+```
+
+Current search parameters for this route (null if not active).
+
+#### `route.hash`
+
+```typescript
+readonly hash: HashType | null
+```
+
+Current hash value for this route (null if not active).
+
+### Utility Methods
+
+#### `route.toUri(params)`
+
+Generate URL string for this route.
+
+```typescript
+const url = router.routes.user.toUri({
+ pathname: { userId: '123' },
+ search: { tab: 'profile' }
+})
+// Returns: "/users/123?tab=profile"
+```
+
+#### `route.toUriExact(params)`
+
+Generate URL string using exact parameters.
+
+## Type Definitions
+
+### Core Types
+
+```typescript
+// Route parameter structure
+interface RouteParams {
+ pathname?: T['pathname']
+ search?: T['search']
+ hash?: T['hash']
+}
+
+// Active route information
+interface ActiveRoute {
+ key: string
+ pathname: Record
+ search: Record
+ hash?: string
+}
+
+// Router configuration
+interface XRouterOptions {
+ useOptimizedObservability?: boolean
+}
+```
+
+### History Types
+
+XRoute uses the standard `history` library types:
+
+```typescript
+import { History, Location } from 'history'
+```
+
+## Configuration Options
+
+### XRouterOptions
+
+#### `useOptimizedObservability`
+
+```typescript
+useOptimizedObservability?: boolean = true
+```
+
+Enables optimized observable updates for better performance. When `true`, only changed properties trigger re-renders.
+
+**Example:**
+```typescript
+const router = new XRouter(
+ routes,
+ history,
+ { useOptimizedObservability: false } // Disable optimization
+)
+```
+
+## Utility Functions
+
+### Route Matching
+
+XRoute internally uses `path-to-regexp` for route matching. You can access these utilities:
+
+```typescript
+import { pathToRegexp, compile } from 'path-to-regexp'
+
+// Generate regex for route matching
+const regex = pathToRegexp('/users/:userId')
+
+// Generate URL from parameters
+const toPath = compile('/users/:userId')
+const url = toPath({ userId: '123' }) // "/users/123"
+```
+
+### Query String Handling
+
+XRoute uses the `qs` library for search parameter serialization:
+
+```typescript
+import qs from 'qs'
+
+// Parse search string
+const params = qs.parse('?tab=profile&items[]=1&items[]=2')
+
+// Stringify parameters
+const search = qs.stringify({ tab: 'profile', items: [1, 2] })
+```
+
+## Error Handling
+
+### Common Errors
+
+#### Route Not Found
+When no route matches the current URL, `router.route` will be `null`.
+
+#### Type Errors
+TypeScript will catch parameter type mismatches at compile time:
+
+```typescript
+// โ Type error - userId should be string
+router.routes.user.push({
+ pathname: { userId: 123 }
+})
+
+// โ
Correct
+router.routes.user.push({
+ pathname: { userId: '123' }
+})
+```
+
+#### Schema Validation
+When using Zod schemas, validation errors are thrown at runtime:
+
+```typescript
+try {
+ router.routes.user.push({
+ pathname: { userId: 'invalid' }
+ })
+} catch (error) {
+ console.error('Validation failed:', error)
+}
+```
+
+## Performance Considerations
+
+### Observable Optimization
+
+- Use `useOptimizedObservability: true` (default) for better performance
+- Wrap components with `observer` only when they read router state
+- Avoid reading router state in render-heavy components
+
+### Route Order
+
+- Place more specific routes before general ones
+- Use catch-all routes sparingly
+- Consider route complexity when ordering
+
+### Memory Management
+
+- Router instances are automatically cleaned up
+- History listeners are managed internally
+- No manual cleanup required in most cases
diff --git a/docs/QuickStart.md b/docs/QuickStart.md
new file mode 100644
index 0000000..26bd665
--- /dev/null
+++ b/docs/QuickStart.md
@@ -0,0 +1,265 @@
+# XRoute Quick Start Guide
+
+Get up and running with XRoute in 5 minutes. This guide walks you through creating a type-safe router for your React application.
+
+## Table of Contents
+
+- [Prerequisites](#prerequisites)
+- [Installation](#installation)
+- [Step 1: Define Routes](#step-1-define-routes)
+- [Step 2: Create Router](#step-2-create-router)
+- [Step 3: React Integration](#step-3-react-integration)
+- [Step 4: Navigation](#step-4-navigation)
+- [Step 5: Reading Route State](#step-5-reading-route-state)
+- [Next Steps](#next-steps)
+
+## Prerequisites
+
+Before starting, ensure you have:
+- Node.js >= 16.0.0
+- A React project with TypeScript
+- Basic familiarity with MobX (optional but recommended)
+
+## Installation
+
+Install XRoute and its peer dependencies:
+
+```bash
+npm install xroute history mobx zod
+```
+
+If using React with MobX:
+```bash
+npm install mobx-react-lite
+```
+
+## Step 1: Define Routes
+
+Create a file `routes.ts` to define your application routes:
+
+```typescript
+// routes.ts
+import { XRoute } from 'xroute'
+
+// Home page route - no parameters
+export const HomeRoute = XRoute('home')
+ .Resource('/')
+ .Type<{
+ pathname: {}
+ search: {}
+ }>()
+
+// User profile route - with path and search parameters
+export const UserRoute = XRoute('user')
+ .Resource('/user/:userId')
+ .Type<{
+ pathname: { userId: string }
+ search: { tab?: 'profile' | 'settings' | 'posts' }
+ }>()
+
+// About page route - simple static route
+export const AboutRoute = XRoute('about')
+ .Resource('/about')
+ .Type<{
+ pathname: {}
+ search: {}
+ }>()
+
+// 404 fallback route - catches unmatched paths
+export const NotFoundRoute = XRoute('notFound')
+ .Resource('/:path(.*)?')
+ .Type<{
+ pathname: { path?: string }
+ search: {}
+ }>()
+```
+
+### Route Definition Explained
+
+- **`XRoute('routeName')`**: Creates a route with a unique identifier
+- **`.Resource('/path')`**: Defines the URL pattern (supports parameters like `:userId`)
+- **`.Type<{ ... }>()`**: Defines TypeScript types for pathname, search, and hash parameters
+
+## Step 2: Create Router
+
+Create a router instance with your routes:
+
+```typescript
+// router.ts
+import { createBrowserHistory } from 'history'
+import { XRouter } from 'xroute'
+import { HomeRoute, UserRoute, AboutRoute, NotFoundRoute } from './routes'
+
+export const router = new XRouter(
+ [
+ UserRoute, // More specific routes first
+ AboutRoute,
+ HomeRoute,
+ NotFoundRoute // Fallback route last
+ ],
+ createBrowserHistory()
+)
+
+// Export router type for use in components
+export type AppRouter = typeof router
+```
+
+### Router Configuration Notes
+
+- **Route Order**: More specific routes should come before general ones
+- **Fallback Route**: Place catch-all routes (like 404) at the end
+- **History**: Use `createBrowserHistory()` for standard web apps, `createHashHistory()` for hash routing
+
+## Step 3: React Integration
+
+Integrate the router with your React application:
+
+```tsx
+// App.tsx
+import React from 'react'
+import { observer } from 'mobx-react-lite'
+import { router } from './router'
+
+// Individual page components
+const HomePage = () => Welcome to the Home Page!
+
+const UserPage = observer(() => {
+ const userId = router.routes.user.pathname?.userId
+ const tab = router.routes.user.search?.tab || 'profile'
+
+ return (
+
+
User Profile: {userId}
+
Active Tab: {tab}
+
+ )
+})
+
+const AboutPage = () => About Us
+
+const NotFoundPage = observer(() => {
+ const path = router.routes.notFound.pathname?.path
+ return Page not found: {path}
+})
+
+// Main App component
+export const App = observer(() => {
+ return (
+
+
+
+
+ {router.route?.key === 'home' && }
+ {router.route?.key === 'user' && }
+ {router.route?.key === 'about' && }
+ {router.route?.key === 'notFound' && }
+
+
+ )
+})
+```
+
+### Integration Notes
+
+- **`observer`**: Wrap components that read router state to enable automatic re-rendering
+- **Route Matching**: Use `router.route?.key` to determine the active route
+- **Type Safety**: All route parameters are fully typed
+
+## Step 4: Navigation
+
+Navigate between routes programmatically:
+
+```typescript
+// Navigate to home page
+router.routes.home.push({})
+
+// Navigate to user profile with parameters
+router.routes.user.push({
+ pathname: { userId: '456' },
+ search: { tab: 'settings' }
+})
+
+// Navigate using the router directly
+router.push(UserRoute, {
+ pathname: { userId: '789' },
+ search: { tab: 'posts' }
+})
+
+// Replace current route (no history entry)
+router.routes.user.replace({
+ pathname: { userId: '123' },
+ search: { tab: 'profile' }
+})
+
+// Navigate with exact parameters (ignores current state)
+router.routes.user.pushExact({
+ pathname: { userId: '999' },
+ search: { tab: 'profile' }
+})
+```
+
+### Navigation Methods
+
+- **`push()`**: Adds new history entry, merges with current parameters
+- **`replace()`**: Replaces current history entry
+- **`pushExact()`**: Ignores current parameters, uses only provided ones
+
+## Step 5: Reading Route State
+
+Access current route information:
+
+```typescript
+// Get active route key
+const activeRoute = router.route?.key // 'home' | 'user' | 'about' | 'notFound'
+
+// Get route-specific parameters (type-safe)
+const userId = router.routes.user.pathname?.userId
+const tab = router.routes.user.search?.tab
+
+// Check if a route is active
+const isUserRouteActive = router.routes.user.isActive
+
+// Get current URL
+const currentUrl = router.location.pathname + router.location.search
+
+// Generate URLs for links
+const userProfileUrl = router.routes.user.toUri({
+ pathname: { userId: '123' },
+ search: { tab: 'profile' }
+}) // "/user/123?tab=profile"
+```
+
+## Next Steps
+
+Congratulations! You now have a working XRoute setup. Here's what to explore next:
+
+### Advanced Features
+- **[Route Inheritance](./Examples.md#route-inheritance)** - Create nested routes
+- **[Schema Validation](./Examples.md#schema-validation)** - Use Zod schemas for validation
+- **[Hash Parameters](./Examples.md#hash-parameters)** - Handle hash-based navigation
+
+### Best Practices
+- **[TypeScript Conventions](./conventions/TypeScript.md)** - Type safety patterns
+- **[React Conventions](./conventions/React.md)** - Component integration patterns
+- **[MobX Conventions](./conventions/MobX.md)** - Observable state management
+
+### Troubleshooting
+- **[Common Issues](./Troubleshooting.md)** - Solutions to frequent problems
+- **[Migration Guide](./Migration.md)** - Upgrading from older versions
+
+### Complete Examples
+- **[Route Definitions](./routeDefinition.ts)** - Comprehensive route examples
+- **[Full Application](./fullExample.tsx)** - Complete React/MobX integration