🔗fast-url

API Reference

Complete API documentation for all fast-url functions with detailed examples and type signatures

API Reference

Complete reference for all functions exported by fast-url.

Type Definitions

ParamMap

The base type for parameter objects used throughout the API.

type ParamMap = Record<string, unknown>;

All parameter values are converted to strings during URL encoding. The following types are supported:

  • string - Used as-is (after URL encoding)
  • number - Converted to string
  • boolean - Converted to 'true' or 'false'
  • Array - Each element becomes a separate parameter with the same key
  • null / undefined - Filtered out and not included in the URL

Main Functions

createUrl()

The primary function for building URLs with multiple overloads for different use cases.

Signature 1: Base Template with Parameters

Build a URL using only a template string with path parameters. Unused parameters become query parameters.

function createUrl(baseTemplate: string, params: ParamMap): string;

Parameters:

  • baseTemplate - A URL template containing zero or more :param placeholders
  • params - Object with properties that correspond to the :params in the template

Returns: A complete URL with path parameters substituted and unused parameters as query string

Example:

import { createUrl } from 'fast-url';

const url = createUrl('http://api.example.com/users/:id', {
  id: 42,
  search: 'foo',
  active: true,
});
console.log(url);
// → 'http://api.example.com/users/42?search=foo&active=true'

Signature 2: Base URL with Path

Concatenate a base URL and path using / as separator. Handles duplicate slashes automatically.

function createUrl(baseUrl: string, path: string): string;

Parameters:

  • baseUrl - The first part of the URL
  • path - The second part of the URL to append

Returns: Concatenated URL with exactly one / separator

Example:

import { createUrl } from 'fast-url';

// Handles trailing/leading slashes
const url1 = createUrl('http://api.example.com/', '/users');
console.log(url1);
// → 'http://api.example.com/users'

// Works without slashes too
const url2 = createUrl('http://api.example.com', 'users');
console.log(url2);
// → 'http://api.example.com/users'

Signature 3: Complete URL Building

Build a complete URL by combining base URL, path template, and parameters.

function createUrl(
  baseUrl: string,
  pathTemplate: string,
  params: ParamMap
): string;

Parameters:

  • baseUrl - The base URL (protocol + domain)
  • pathTemplate - Path template with optional :param placeholders
  • params - Object with path and query parameters

Returns: Complete URL with substituted path parameters and query string

Example:

import { createUrl } from 'fast-url';

const url = createUrl('http://api.example.com/', '/users/:id', {
  id: 42,
  search: 'foo',
  limit: 10,
  offset: 20,
});
console.log(url);
// → 'http://api.example.com/users/42?search=foo&limit=10&offset=20'

Path vs Query Parameters

Parameters that match :param placeholders in the path template are used for path substitution. All other parameters become query string parameters.


Utility Functions

query()

Build a query string from a parameter object.

function query(params: ParamMap): string;

Parameters:

  • params - Object to convert into a query string

Returns: URL-encoded query string (without leading ?)

Examples:

import { query } from 'fast-url';

// Basic usage
const q1 = query({ name: 'John', age: 30 });
console.log(q1);
// → 'name=John&age=30'

// Special characters are encoded
const q2 = query({
  search: 'hello world',
  filter: 'price>100',
});
console.log(q2);
// → 'search=hello%20world&filter=price%3E100'

// Arrays create repeated parameters
const q3 = query({
  tags: ['javascript', 'typescript'],
  limit: 10,
});
console.log(q3);
// → 'tags=javascript&tags=typescript&limit=10'

// Null and undefined are filtered out
const q4 = query({
  name: 'John',
  age: null,
  city: undefined,
  country: 'USA',
});
console.log(q4);
// → 'name=John&country=USA'

// Empty object returns empty string
const q5 = query({});
console.log(q5);
// → ''

Use Cases:

  • Building query strings independently
  • Updating existing URLs with new parameters
  • Creating search or filter parameters

subst()

Substitute path parameters in a template string without building a full URL.

function subst(template: string, params: ParamMap): string;

Parameters:

  • template - String containing :param placeholders
  • params - Object with keys matching the placeholders

Returns: Template with all :param placeholders replaced with URL-encoded values

Examples:

import { subst } from 'fast-url';

// Basic substitution
const path1 = subst('/users/:id/posts/:postId', {
  id: 42,
  postId: 123,
});
console.log(path1);
// → '/users/42/posts/123'

// Extra parameters are ignored
const path2 = subst('/users/:id', {
  id: 42,
  limit: 10, // Ignored
  sort: 'name', // Ignored
});
console.log(path2);
// → '/users/42'

// Special characters in values are encoded
const path3 = subst('/search/:query', {
  query: 'hello world & goodbye',
});
console.log(path3);
// → '/search/hello%20world%20%26%20goodbye'

// Unicode is properly handled
const path4 = subst('/users/:name', {
  name: '田中',
});
console.log(path4);
// → '/users/%E7%94%B0%E4%B8%AD'

Errors:

import { subst } from 'fast-url';

// Missing parameter throws error
try {
  subst('/users/:id', {});
} catch (error) {
  console.error(error.message);
  // → "Missing value for path parameter id."
}

// Invalid type throws error
try {
  subst('/users/:id', { id: {} });
} catch (error) {
  console.error(error.message);
  // → "Path parameter id cannot be of type object. Allowed types are: boolean, string, number."
}

// Empty string throws error
try {
  subst('/users/:id', { id: '' });
} catch (error) {
  console.error(error.message);
  // → "Path parameter id cannot be an empty string."
}

Use Cases:

  • Building URL paths without query strings
  • Template rendering
  • Path parameter validation

join()

Join two strings using a separator, ensuring exactly one occurrence at the boundary.

function join(part1: string, separator: string, part2: string): string;

Parameters:

  • part1 - First string
  • separator - Separator character(s)
  • part2 - Second string

Returns: Joined string with exactly one separator

Examples:

import { join } from 'fast-url';

// URL path joining
const url1 = join('http://api.example.com/', '/', '/users');
console.log(url1);
// → 'http://api.example.com/users'

// Works with different separators
const url2 = join('http://api.example.com', '/', 'users');
console.log(url2);
// → 'http://api.example.com/users'

// Query string joining
const query1 = join('name=John', '&', '&age=30');
console.log(query1);
// → 'name=John&age=30'

// Handles empty strings
const url3 = join('', '/', 'users');
console.log(url3);
// → 'users'

const url4 = join('http://api.example.com', '/', '');
console.log(url4);
// → 'http://api.example.com'

// Multiple character separators
const text = join('Hello', ', ', ', World');
console.log(text);
// → 'Hello, World'

Use Cases:

  • Safe URL concatenation
  • Building paths from segments
  • Joining strings with any separator

Advanced Examples

Building Complex API Clients

import { createUrl, query } from 'fast-url';

class GitHubAPI {
  private baseUrl = 'https://api.github.com';

  // List user repositories with filters
  getUserRepos(
    username: string,
    options: {
      type?: 'all' | 'owner' | 'member';
      sort?: 'created' | 'updated' | 'pushed' | 'full_name';
      direction?: 'asc' | 'desc';
      per_page?: number;
      page?: number;
    } = {}
  ) {
    return createUrl(this.baseUrl, '/users/:username/repos', {
      username,
      ...options,
    });
  }

  // Get a specific commit
  getCommit(owner: string, repo: string, sha: string) {
    return createUrl(this.baseUrl, '/repos/:owner/:repo/commits/:sha', {
      owner,
      repo,
      sha,
    });
  }

  // Search repositories
  searchRepos(
    q: string,
    options: {
      sort?: 'stars' | 'forks' | 'updated';
      order?: 'asc' | 'desc';
      per_page?: number;
    } = {}
  ) {
    return createUrl(this.baseUrl, '/search/repositories', {
      q,
      ...options,
    });
  }
}

const github = new GitHubAPI();

console.log(
  github.getUserRepos('octocat', {
    type: 'owner',
    sort: 'updated',
    per_page: 50,
  })
);
// → https://api.github.com/users/octocat/repos?type=owner&sort=updated&per_page=50

console.log(github.getCommit('facebook', 'react', 'abc123'));
// → https://api.github.com/repos/facebook/react/commits/abc123

console.log(
  github.searchRepos('fast-url language:typescript', {
    sort: 'stars',
    order: 'desc',
  })
);
// → https://api.github.com/search/repositories?q=fast-url%20language%3Atypescript&sort=stars&order=desc

Dynamic Route Building

import { createUrl } from 'fast-url';

// Route configuration
const routes = {
  home: '/',
  userProfile: '/users/:userId',
  userPosts: '/users/:userId/posts',
  post: '/posts/:postId',
  search: '/search',
};

// Helper to build routes
function route(name: keyof typeof routes, params: Record<string, any> = {}) {
  return createUrl('https://myblog.com', routes[name], params);
}

console.log(route('home'));
// → https://myblog.com/

console.log(route('userProfile', { userId: 123 }));
// → https://myblog.com/users/123

console.log(route('userPosts', { userId: 123, page: 2 }));
// → https://myblog.com/users/123/posts?page=2

console.log(route('search', { q: 'typescript', tag: 'tutorial' }));
// → https://myblog.com/search?q=typescript&tag=tutorial

Pagination Helper

import { createUrl } from 'fast-url';

function buildPaginatedUrl(
  baseUrl: string,
  path: string,
  page: number,
  pageSize: number,
  filters: Record<string, any> = {}
) {
  return createUrl(baseUrl, path, {
    ...filters,
    page,
    per_page: pageSize,
    offset: (page - 1) * pageSize,
  });
}

console.log(
  buildPaginatedUrl('https://api.example.com', '/products', 3, 20, {
    category: 'electronics',
    sort: 'price',
  })
);
// → https://api.example.com/products?category=electronics&sort=price&page=3&per_page=20&offset=40

Performance Notes

fast-url is optimized for performance:

  • Query string encoding: Matches Node.js performance with optimized implementations
  • Direct constant access: Better V8 JIT optimization
  • Minimal allocations: Efficient memory usage
  • Zero dependencies: Only relies on fast-querystring

Benchmarks

In performance benchmarks, fast-url achieves 5-20% better performance than the original urlcat implementation in many scenarios while maintaining full compatibility.

Browser and Node.js Compatibility

fast-url works in all modern JavaScript environments:

  • ✅ Node.js 14+
  • ✅ Bun
  • ✅ Deno
  • ✅ Modern browsers (Chrome, Firefox, Safari, Edge)
  • ✅ React Native
  • ✅ Electron

Next Steps