🔗fast-url

Getting Started

Quick start guide to install and use fast-url in your JavaScript or TypeScript project

Getting Started

Get up and running with fast-url in minutes. This guide will walk you through installation and basic usage.

Installation

Install fast-url using your preferred package manager:

bun add fast-url
pnpm add fast-url
yarn add fast-url
npm install fast-url
deno add jsr:@hckhanh/fast-url

TypeScript Support

fast-url is written in TypeScript and includes type definitions out of the box. No need to install separate @types packages!

Basic Usage

Importing

import { createUrl } from 'fast-url';
const { createUrl } = require('fast-url');

Quick Examples

Here are some common use cases to get you started:

Path Parameters

Replace placeholders in a URL path with actual values:

import { createUrl } from 'fast-url';

const userId = 123;
const url = createUrl('https://api.example.com', '/users/:id', { id: userId });
console.log(url);
// → 'https://api.example.com/users/123'

Query Parameters

Add query string parameters to a URL:

import { createUrl } from 'fast-url';

const url = createUrl('https://api.example.com', '/users', {
  limit: 10,
  offset: 20,
  sort: 'name',
});
console.log(url);
// → 'https://api.example.com/users?limit=10&offset=20&sort=name'

Combined Path and Query Parameters

Mix path substitution with query parameters:

import { createUrl } from 'fast-url';

const url = createUrl('https://api.example.com', '/users/:id/posts', {
  id: 123,
  limit: 10,
  published: true,
});
console.log(url);
// → 'https://api.example.com/users/123/posts?limit=10&published=true'

Step-by-Step Tutorial

Let's build a simple REST API client using fast-url:

Create the API Client Class

Start by creating a basic API client structure:

import { createUrl } from 'fast-url';

class BlogAPI {
  private baseUrl = 'https://api.blog.com';
  
  constructor(apiKey: string) {
    this.apiKey = apiKey;
  }
}

Add a Method to Fetch Posts

Use createUrl to build the endpoint URL with query parameters:

async getPosts(options = {}) {
  const url = createUrl(this.baseUrl, '/posts', {
    page: options.page || 1,
    limit: options.limit || 10,
    tag: options.tag
  });
  
  const response = await fetch(url, {
    headers: { 'Authorization': `Bearer ${this.apiKey}` }
  });
  
  return response.json();
}

Add a Method to Fetch a Single Post

Use path parameters for resource IDs:

async getPost(postId: number) {
  const url = createUrl(this.baseUrl, '/posts/:id', { id: postId });
  
  const response = await fetch(url, {
    headers: { 'Authorization': `Bearer ${this.apiKey}` }
  });
  
  return response.json();
}

Use the API Client

Now you can use your API client with clean, type-safe URLs:

const api = new BlogAPI('your-api-key');

// Fetch paginated posts with a tag filter
const posts = await api.getPosts({ 
  page: 2, 
  limit: 20, 
  tag: 'javascript' 
});
// URL: https://api.blog.com/posts?page=2&limit=20&tag=javascript

// Fetch a specific post
const post = await api.getPost(42);
// URL: https://api.blog.com/posts/42

Common Patterns

Handling Optional Parameters

fast-url automatically filters out null and undefined values:

import { createUrl } from 'fast-url';

const url = createUrl('https://api.example.com', '/search', {
  q: 'javascript',
  category: null, // Will be omitted
  author: undefined, // Will be omitted
  limit: 10,
});
console.log(url);
// → 'https://api.example.com/search?q=javascript&limit=10'

Working with Arrays

Arrays are automatically converted to repeated parameters:

import { query } from 'fast-url';

const queryString = query({
  tags: ['javascript', 'typescript', 'node'],
  limit: 10,
});
console.log(queryString);
// → 'tags=javascript&tags=typescript&tags=node&limit=10'

Building Query Strings Only

Use the query helper when you only need a query string:

import { query } from 'fast-url';

const params = query({
  name: 'John Doe',
  age: 30,
  city: 'New York',
});
console.log(params);
// → 'name=John%20Doe&age=30&city=New%20York'

Substituting Path Parameters Only

Use subst when you only need path parameter substitution:

import { subst } from 'fast-url';

const path = subst('/users/:userId/posts/:postId', {
  userId: 123,
  postId: 456,
});
console.log(path);
// → '/users/123/posts/456'

Joining URL Parts

Use join to safely concatenate URL segments:

import { join } from 'fast-url';

const url = join('https://api.example.com/', '/', '/users');
console.log(url);
// → 'https://api.example.com/users'

// Works with any separator
const query = join('name=John', '&', '&age=30');
console.log(query);
// → 'name=John&age=30'

Special Characters and Unicode

fast-url properly handles special characters and Unicode:

import { createUrl } from 'fast-url';

// Special characters are automatically encoded
const url1 = createUrl('https://api.example.com', '/search', {
  q: 'hello world & goodbye',
  filter: 'price>100',
});
// → 'https://api.example.com/search?q=hello%20world%20%26%20goodbye&filter=price%3E100'

// Unicode characters are properly handled
const url2 = createUrl('https://api.example.com', '/users/:name', {
  name: '田中太郎',
});
// → 'https://api.example.com/users/%E7%94%B0%E4%B8%AD%E5%A4%AA%E9%83%8E'

// Even emojis work correctly
const url3 = createUrl('https://api.example.com', '/posts', {
  mood: '😊🎉',
});
// → 'https://api.example.com/posts?mood=%F0%9F%98%8A%F0%9F%8E%89'

Error Handling

fast-url validates path parameters and throws helpful errors:

import { createUrl } from 'fast-url';

try {
  // Missing required path parameter
  createUrl('https://api.example.com', '/users/:id', {});
} catch (error) {
  console.error(error.message);
  // → "Missing value for path parameter id."
}

try {
  // Invalid path parameter type
  createUrl('https://api.example.com', '/users/:id', {
    id: { invalid: 'object' },
  });
} catch (error) {
  console.error(error.message);
  // → "Path parameter id cannot be of type object. Allowed types are: boolean, string, number."
}

try {
  // Empty string path parameter
  createUrl('https://api.example.com', '/users/:id', { id: '' });
} catch (error) {
  console.error(error.message);
  // → "Path parameter id cannot be an empty string."
}

Type Safety

When using TypeScript, many of these errors can be caught at compile time thanks to fast-url's type definitions!

Next Steps