diff --git a/.browserslistrc b/.browserslistrc
new file mode 100644
index 00000000..7f723f31
--- /dev/null
+++ b/.browserslistrc
@@ -0,0 +1,13 @@
+# Fixed ES2022 browser baseline for Wouter 4; see specs/browser-support.md.
+# Packages ship source. This is a consumer/tooling target, not a build step.
+Chrome >= 94
+and_chr >= 94
+Edge >= 94
+Firefox >= 93
+and_ff >= 93
+Safari >= 16.4
+ios_saf >= 16.4
+Opera >= 80
+op_mob >= 66
+Samsung >= 17
+Android >= 94
diff --git a/.cursor/rules/contributing.mdc b/.cursor/rules/contributing.mdc
deleted file mode 100644
index 5c637e65..00000000
--- a/.cursor/rules/contributing.mdc
+++ /dev/null
@@ -1,242 +0,0 @@
----
-description:
-globs:
-alwaysApply: true
----
-
-# Wouter - Minimalist React Router
-
-## Project Overview
-
-Wouter is a **minimalist-friendly ~2.1KB React router** that focuses on performance, small bundle size, and simplicity. It provides hook-based routing for React and Preact applications.
-
-### Key Features
-
-- Tiny bundle size (2.1KB gzipped vs 18.7KB React Router)
-- Hook-based API (`useLocation`, `useRoute`, `useParams`, etc.)
-- Zero dependencies
-- Supports React and Preact
-- Optional top-level `` component
-- Nested routing support
-- SSR support
-- Memory location for testing
-
-## Project Structure
-
-```
-wouter/
-├── packages/
-│ ├── wouter/ # Main React package
-│ │ ├── src/
-│ │ │ ├── index.js # Main router implementation
-│ │ │ ├── use-browser-location.js
-│ │ │ ├── use-hash-location.js
-│ │ │ ├── memory-location.js
-│ │ │ ├── react-deps.js # React imports
-│ │ │ └── paths.js # Path utilities
-│ │ ├── test/ # Test files
-│ │ ├── types/ # TypeScript definitions
-│ │ └── esm/ # Built ES modules
-│ └── wouter-preact/ # Preact package
-├── assets/ # Documentation assets
-└── .github/ # GitHub workflows
-```
-
-## Development Workflow
-
-### Prerequisites
-
-- Node.js v20.17.0+ or v22.9.0+
-- npm
-
-### Commands
-
-```bash
-# Install dependencies
-npm install
-
-# Run tests (watch mode)
-npm test
-
-# Run tests (single run)
-npm test -- --run
-
-# Run specific test file
-npm test -- packages/wouter/test/router.test.tsx --run
-
-# Run tests with coverage
-npm test -- --coverage
-
-# Build packages
-npm run build
-
-# Type checking
-npm run typecheck
-
-# Lint code
-npm run lint
-```
-
-### Test Files Organization
-
-- `test/router.test.tsx` - Router component and memoization tests
-- `test/use-location.test.tsx` - Location hook tests
-- `test/use-route.test.tsx` - Route matching tests
-- `test/link.test.tsx` - Link component tests
-- `test/memory-location.test.ts` - Memory location for testing
-- `test/nested-route.test.tsx` - Nested routing tests
-- `test/ssr.test.tsx` - Server-side rendering tests
-
-## Key Development Principles
-
-### Performance First
-
-- **Bundle size matters**: Every byte counts. Use size-limit CI checks
-- **Stable object references**: Prevent unnecessary re-renders with proper memoization
-- **Minimize dependencies**: Zero external dependencies policy
-
-### Code Style
-
-- **Functional programming**: Prefer hooks over class components
-- **Compact code**: Optimize for bundle size (may sacrifice readability)
-- **React patterns**: Use `React.memo`, `useCallback`, `useMemo` appropriately
-
-### Testing Guidelines
-
-- **Comprehensive coverage**: Test all public APIs
-- **Real-world scenarios**: Include complex use cases (like language switching)
-- **Memory location**: Use for isolated testing
-- **Memoization tests**: Verify stable object references
-
-## Core APIs
-
-### Hooks
-
-- `useLocation()` - Get/set current location
-- `useRoute(pattern)` - Match current location against pattern
-- `useParams()` - Extract route parameters
-- `useSearch()` - Get search/query string
-- `useSearchParams()` - Get/set URLSearchParams
-- `useRouter()` - Access router configuration
-
-### Components
-
-- `` - Optional configuration wrapper
-- `` - Conditional rendering based on path
-- `` - Navigation component
-- `` - Exclusive routing
-- `` - Programmatic navigation
-
-### Location Hooks
-
-- `useBrowserLocation` - Browser history API
-- `useHashLocation` - Hash-based routing
-- `memoryLocation` - In-memory for testing
-
-## Performance Considerations
-
-### Router Memoization
-
-The Router component uses sophisticated memoization to prevent unnecessary re-renders:
-
-- Only creates new router objects when props actually change
-- Preserves stable references for `React.memo` components
-- Critical for performance in complex applications
-
-### Bundle Optimization
-
-- Use `// ... existing code ...` pattern in edits to minimize diffs
-- Prefer shorter variable names in production builds
-- Optimize for gzip/brotli compression
-
-## Common Patterns
-
-### Testing Router Components
-
-```javascript
-import { memoryLocation } from "wouter/memory-location";
-
-const { hook } = memoryLocation({ path: "/test/path" });
-render(
-
-
-
-);
-```
-
-### Custom Location Hooks
-
-```javascript
-const useCustomLocation = () => {
- const [location, setLocation] = useBrowserLocation();
- // Add custom logic here
- return [location, setLocation];
-};
-```
-
-### Nested Routing
-
-```javascript
-
-
-
-
-
-```
-
-## Debugging Tips
-
-### Common Issues
-
-1. **Router memoization**: Check if unnecessary re-renders occur
-2. **Base path conflicts**: Verify base path inheritance in nested routers
-3. **Pattern matching**: Use regexparam syntax for route patterns
-4. **SSR hydration**: Ensure client/server router configs match
-
-### Debugging Tools
-
-- React DevTools Profiler for render tracking
-- Network tab for bundle size verification
-- Console warnings for deprecated patterns
-
-## Contributing Guidelines
-
-### Before Making Changes
-
-1. Run full test suite: `npm test -- --run`
-2. Check bundle size impact
-3. Verify TypeScript definitions
-4. Test with both React and Preact
-
-### Adding New Features
-
-1. Consider bundle size impact
-2. Add comprehensive tests
-3. Update TypeScript definitions
-4. Document in README if public API
-5. Maintain backward compatibility
-
-### Performance Changes
-
-1. Add before/after performance tests
-2. Verify memoization behavior
-3. Test with complex nested scenarios
-4. Check for memory leaks in long-running apps
-
-## Architecture Notes
-
-### Router Context System
-
-- Default router created on-demand
-- Context inheritance with override capabilities
-- Memoization prevents cascade re-renders
-- Base path accumulation in nested routers
-
-### Pattern Matching
-
-- Uses regexparam library internally
-- Supports named parameters, wildcards, optional segments
-- Regex patterns supported for complex matching
-- Loose mode for nested routing
-
-This project prioritizes performance and minimalism while maintaining full feature parity with larger routing solutions.
diff --git a/.cursor/rules/publishing.mdc b/.cursor/rules/publishing.mdc
deleted file mode 100644
index dc89c544..00000000
--- a/.cursor/rules/publishing.mdc
+++ /dev/null
@@ -1,109 +0,0 @@
----
-description:
-globs:
-alwaysApply: true
----
-# Publishing Wouter Packages
-
-This document outlines the process for publishing new versions of the wouter packages to npm.
-
-## Prerequisites
-
-- Ensure you have npm publish permissions for both `wouter` and `wouter-preact` packages
-- Have npm authentication set up (you'll need OTP access)
-- All tests should be passing
-- All changes should be committed to the repository
-
-## Publishing Process
-
-### 1. Version Bump
-
-Update the version in both package.json files:
-- `packages/wouter/package.json`
-- `packages/wouter-preact/package.json`
-
-For semantic versioning:
-- **Patch** (x.x.X): Bug fixes, small improvements
-- **Minor** (x.X.x): New features, backward compatible
-- **Major** (X.x.x): Breaking changes
-
-### 2. Dry Run Validation
-
-Run dry publish commands to validate the packages before actual publishing:
-
-```bash
-npm publish --dry-run -w wouter
-npm publish --dry-run -w wouter-preact
-```
-
-This will show you:
-- Package contents and file list
-- Bundle size information
-- Version confirmation
-- Any potential issues
-
-### 3. Build Verification (Optional)
-
-Check the build artifacts in the `/esm/` folders to ensure the latest updates are properly built:
-- `packages/wouter/esm/`
-- `packages/wouter-preact/esm/`
-
-The `prepublishOnly` script automatically builds the packages, but it's good to verify.
-
-## ⚠️ Confirmation Required
-
-**ALWAYS ask for user confirmation before proceeding with the following steps:**
-
-### 4. Publish to npm
-
-Publish both packages to the npm registry:
-
-```bash
-npm publish -w wouter
-npm publish -w wouter-preact
-```
-
-**Note:** npm might fail with "EOTP" (Error One-Time Password) even when the OTP was entered correctly in the browser. This is a known npm issue - the packages are usually still published successfully despite the error message.
-
-### 5. Git Commit and Tag
-
-After successful publishing:
-
-1. **Commit the version changes:**
- ```bash
- git add packages/wouter/package.json packages/wouter-preact/package.json
- git commit -m "Bump version to X.X.X"
- ```
-
-2. **Create a version tag:**
- ```bash
- git tag vX.X.X
- ```
-
-3. **Push to remote (optional):**
- ```bash
- git push origin main
- git push origin vX.X.X
- ```
-
-## Troubleshooting
-
-### Common Issues
-
-- **Authentication errors**: Run `npm login` or use the browser authentication flow
-- **OTP timeout**: Generate a fresh OTP code from your authenticator app
-- **Permission denied**: Ensure you have publish permissions for both packages
-- **Version conflicts**: Check if the version already exists on npm
-
-### Verification
-
-After publishing, verify the packages are available:
-- Check [wouter on npm](mdc:https:/www.npmjs.com/package/wouter)
-- Check [wouter-preact on npm](mdc:https:/www.npmjs.com/package/wouter-preact)
-- Test installation: `npm install wouter@latest`
-
-## Package Information
-
-- **wouter**: Main React package (~22KB package size)
-- **wouter-preact**: Preact-specific package (~22KB package size)
-- Both packages maintain version parity and should be published together
\ No newline at end of file
diff --git a/.github/workflows/ci-tests.yml b/.github/workflows/ci-tests.yml
index b727ae64..591b292d 100644
--- a/.github/workflows/ci-tests.yml
+++ b/.github/workflows/ci-tests.yml
@@ -25,7 +25,7 @@ jobs:
run: bun install --frozen-lockfile
- name: Prepare wouter-preact (copy source files)
- run: cd packages/wouter-preact && npm run prepublishOnly
+ run: bun run --cwd packages/wouter-preact prepublishOnly
- name: Run test
run: bun test --coverage --coverage-reporter=lcov --coverage-reporter=text
@@ -40,3 +40,39 @@ jobs:
uses: coverallsapp/github-action@v2
with:
file: ./coverage/lcov.info
+
+ react-compatibility:
+ runs-on: ubuntu-latest
+ strategy:
+ matrix:
+ react: ["18.2.0", "18.3.1", "19.0.0"]
+ steps:
+ - uses: actions/checkout@v4
+ - uses: oven-sh/setup-bun@v2
+ with:
+ bun-version: latest
+ - run: bun install --frozen-lockfile
+ - name: Install the React version under test
+ run: bun add --dev --exact react@${{ matrix.react }} react-dom@${{ matrix.react }}
+ - name: Test supported React versions
+ run: bun test packages/wouter/test
+
+ typescript-consumers:
+ runs-on: ubuntu-latest
+ strategy:
+ matrix:
+ typescript: ["5.2.2", "workspace"]
+ react-types: ["18", "19"]
+ steps:
+ - uses: actions/checkout@v4
+ - uses: oven-sh/setup-bun@v2
+ with:
+ bun-version: latest
+ - run: bun install --frozen-lockfile
+ - name: Install React declarations under test
+ run: bun add --dev @types/react@${{ matrix.react-types }} @types/react-dom@${{ matrix.react-types }}
+ - name: Install the minimum supported TypeScript version
+ if: matrix.typescript != 'workspace'
+ run: bun add --dev --exact typescript@${{ matrix.typescript }}
+ - name: Check strict React and Preact consumers
+ run: bun run test-types:consumer
diff --git a/AGENTS.md b/AGENTS.md
index b8100b77..2b6d7d2d 100644
--- a/AGENTS.md
+++ b/AGENTS.md
@@ -1,111 +1,140 @@
----
-description: Use Bun instead of Node.js, npm, pnpm, or vite.
-globs: "*.ts, *.tsx, *.html, *.css, *.js, *.jsx, package.json"
-alwaysApply: false
----
+# Working on Wouter
+
+This is the shared project guide for coding agents. Keep it
+focused on durable conventions; use the source, package scripts, and CI workflows
+for details that change frequently.
+
+## Project and layout
+
+Wouter is a small, hook-based router for React and Preact. Prioritize a small
+bundle, few dependencies, stable references, and predictable routing behavior.
+`regexparam` is a runtime dependency; this is not a zero-dependency project.
+
+- `packages/wouter/src/`: canonical JavaScript implementation, shipped directly
+ as ES modules. The root `build` script is a no-op; there is no required `esm/`
+ build output.
+- `packages/wouter-preact/`: shares Wouter's runtime sources except for its own
+ `src/react-deps.js` adapter. Shared files are copied by `prepublishOnly` and
+ ignored by Git. Edit the canonical sources instead of the generated copies.
+- `packages/*/types/`: hand-maintained TypeScript declarations. Keep React and
+ Preact declarations aligned while preserving framework-specific types. Wouter's
+ `src/*.d.ts` files forward to these declarations for source imports.
+- `packages/*/test/`: runtime tests and declaration tests (`*.test-d.ts[x]`).
+- `packages/magazin/`: private storefront demo using Bun, React, SSR, and Tailwind.
+- `README.md`: canonical public documentation; package READMEs are copied from it.
+ [specs/browser-support.md](specs/browser-support.md) records the Wouter 4
+ compatibility decisions and their rationale.
+
+## Tooling and checks
+
+Use Bun for installation, scripts, tests, and builds. Keep the single root
+`bun.lock`; do not introduce nested lockfiles or a second package manager.
+Prefer Bun's built-in APIs (`Bun.file`, `Bun.serve`, `Bun.build`, `Bun.$`) for
+new tooling. Bun loads `.env` automatically. Demo frontend work uses Bun's HTML
+entrypoints rather than Vite.
+
+Run commands from the repository root unless specified otherwise:
-Default to using Bun instead of Node.js.
-
-- Use `bun ` instead of `node ` or `ts-node `
-- Use `bun test` instead of `jest` or `vitest`
-- Use `bun build ` instead of `webpack` or `esbuild`
-- Use `bun install` instead of `npm install` or `yarn install` or `pnpm install`
-- Use `bun run
-