npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

typelit

v0.2.0

Published

A type-safe string templating library for TypeScript

Readme

Typelit

"Type-safe template string literals"

NPM Version npm bundle size dependency count GitHub Actions Workflow Status GitHub License

A type-safe string templating library for TypeScript that provides strongly-typed variable references with support for nested paths. Create template strings with compile-time type checking and automatic context type inference.

Typelit allows you to write template strings that are both type-safe and easy to read. Variables are referenced using a familiar template literal syntax while maintaining full type information about the required context object structure.

Table of contents

Getting Started

Installation

Install using npm:

npm install typelit

Or using yarn:

yarn add typelit

The library is available in multiple module formats to support different environments:

  • CommonJS (Node.js):
const typelit = require('typelit');
const greeting = typelit`Hello ${typelit.string('name')}!`;
  • ESM (Modern JavaScript):
import typelit from 'typelit';
const greeting = typelit`Hello ${typelit.string('name')}!`;
  • UMD (Browser):
<script src="https://unpkg.com/typelit"></script>
<script>
  const greeting = typelit`Hello ${typelit.string('name')}!`;
</script>

Each format provides identical functionality - pick the one that best suits your environment. The library includes TypeScript type definitions that work automatically with all formats.

Basic Usage

First, import the library:

import typelit from 'typelit';

Let's start with a simple greeting template:

// Create a simple template with one variable
const greeting = typelit`Hello ${typelit.string('name')}!`;

// Use the template with a context object
const result = greeting({ name: 'Alice' }); // "Hello Alice!"

Nested Context Objects

You can also create templates with nested variable paths:

// Create a template with nested variables
const template = typelit`Hello ${typelit.string('user', 'name')}! You are ${typelit.number('user', 'age')} years old.`;

// TypeScript knows exactly what shape the context object needs to have
const result = template({
  user: {
    name: 'Alice',
    age: 30,
  },
}); // "Hello Alice! You are 30 years old."

// This would cause a type error:
template({
  user: {
    name: 'Bob',
    // Error: missing required property 'age'
  },
});

Template Function

The typelit tag function creates template functions that evaluate a string template using values from a context object. The template function takes a context object as input and returns the evaluated string with all variables replaced by their values.

When creating a template, TypeScript infers the required shape of the context object from the variables used in the template.

// Example showing type inference
const welcome = typelit`Welcome back, ${typelit.string('username')}!`;

// TypeScript infers that the context must have a 'username' property
welcome({ username: 'alice' }); // OK
welcome({ user: 'bob' }); // Type error: missing username
welcome({ username: 123 }); // Type error: number is not assignable to string

Features

The typelit function serves a dual purpose:

  1. As a template tag function that creates typed template functions
  2. As a namespace that provides variable creators (string, number, etc.)

Template functions created with typelit offer:

  • Type Safety: All variables are fully typed, ensuring you can't pass the wrong type of value.
  • Path Inference: TypeScript automatically infers the required structure of your context object.
  • Composition: Templates can be composed to build more complex strings:
const firstName = typelit`${typelit.string('user', 'firstName')}`;
const lastName = typelit`${typelit.string('user', 'lastName')}`;
const fullName = typelit`${firstName} ${lastName}`;

// Both templates require the same context structure
firstName({ user: { firstName: 'John' } });
fullName({ user: { firstName: 'John', lastName: 'Doe' } });
  • Compile-Time Validation: TypeScript catches errors before runtime:
    • Missing or misspelled variable paths
    • Incorrect value types
    • Missing context properties
    • Invalid template syntax

Variable Creators

Typelit provides built-in variable creators for common data types. These are used to define variables in your templates with type-safe paths.

String

Use typelit.string() to create string variables in your templates:

// Simple string variable
const greeting = typelit`Hello ${typelit.string('name')}!`;
greeting({ name: 'Alice' }); // "Hello Alice!"

// Nested string variable
const userEmail = typelit`Contact: ${typelit.string('user', 'email')}`;
userEmail({ user: { email: '[email protected]' } }); // "Contact: [email protected]"

Number

Use typelit.number() to create number variables:

// Simple number variable
const age = typelit`Age: ${typelit.number('age')} years old`;
age({ age: 25 }); // "Age: 25 years old"

// Nested number variable
const score = typelit`Score: ${typelit.number('game', 'score')} points`;
score({ game: { score: 100 } }); // "Score: 100 points"

Boolean

Use typelit.boolean() to create boolean variables:

// Simple boolean variable
const status = typelit`Status: ${typelit.boolean('isActive')}`;
status({ isActive: true }); // "Status: true"

// Nested boolean variable
const accountStatus = typelit`Account active: ${typelit.boolean('user', 'account', 'enabled')}`;
accountStatus({ user: { account: { enabled: false } } }); // "Account active: false"

BigInt

Use typelit.bigint() to create bigint variables:

// Simple bigint variable
const id = typelit`ID: ${typelit.bigint('userId')}`;
id({ userId: 9007199254740991n }); // "ID: 9007199254740991"

// Nested bigint variable
const transactionId = typelit`Transaction: ${typelit.bigint('payment', 'transactionId')}`;
transactionId({ payment: { transactionId: 123456789n } }); // "Transaction: 123456789"

Date

Use typelit.date() to create Date variables that automatically convert JavaScript Date objects to strings:

// Simple date variable
const eventDate = typelit`Event date: ${typelit.date('date')}`;
eventDate({ date: new Date('2024-12-25') }); // "Event date: Wed Dec 25 2024 00:00:00 GMT+0000"

// Nested date variable
const appointmentTime = typelit`Appointment scheduled for: ${typelit.date('calendar', 'appointment')}`;
appointmentTime({
  calendar: { appointment: new Date('2024-12-25T15:30:00Z') },
}); // "Appointment scheduled for: Wed Dec 25 2024 15:30:00 GMT+0000"

JSON

Use typelit.json() to create variables that automatically stringify any value to JSON with proper formatting:

// Simple JSON variable
const data = typelit`Data: ${typelit.json('config')}`;
data({ config: { enabled: true, count: 42 } });
// "Data: {
//   "enabled": true,
//   "count": 42
// }"

// Nested JSON variable
const userProfile = typelit`Profile: ${typelit.json('user', 'profile')}`;
userProfile({
  user: {
    profile: {
      name: 'Alice',
      preferences: {
        theme: 'dark',
        notifications: true,
      },
    },
  },
});
// "Profile: {
//   "name": "Alice",
//   "preferences": {
//     "theme": "dark",
//     "notifications": true
//   }
// }"

Custom Variable Creators

You can create your own variable creators for any type using the createType function. Here's a basic example creating a variable creator for JavaScript's Date type:

import { createType } from 'typelit';

// Create a variable creator for Date
const typelitDate = createType<Date>();

// Use it in a template
const template = typelit`Event starts at ${typelitDate('event', 'startTime')}`;

// The context object requires a Date instance
const result = template({
  event: {
    startTime: new Date('2024-12-25T10:00:00Z'),
  },
}); // "Event starts at Wed Dec 25 2024 10:00:00 GMT+0000"

// Type error: string is not assignable to Date
template({
  event: {
    startTime: '2024-12-25', // Error!
  },
});

Like built-in variable creators, custom ones:

  • Support nested paths
  • Provide full type inference for the context object
  • Enforce the correct type at compile time

Customizing String Conversion

The createType function accepts an optional options. The options.stringify parameter is a function that takes a value of your type and returns a string.

Here are some examples of customizing string conversion:

// Custom date formatting
const typelitDate = createType<Date>({
  stringify: (date) =>
    date.toLocaleDateString('en-US', {
      weekday: 'short',
      month: 'short',
      day: 'numeric',
      year: 'numeric',
    }),
});

const event = typelit`Event: ${typelitDate('date')}`;
event({ date: new Date('2024-12-25') }); // "Event: Wed, Dec 25, 2024"

// Currency formatting
const typelitPrice = createType<number>({
  stringify: (price) =>
    new Intl.NumberFormat('en-US', {
      style: 'currency',
      currency: 'USD',
    }).format(price),
});

const price = typelit`Total: ${typelitPrice('amount')}`;
price({ amount: 42.99 }); // "Total: $42.99"

// Custom object formatting
type User = { id: number; name: string };
const typelitUser = createType<User>({
  stringify: (user) => `#${user.id} ${user.name}`,
});

const user = typelit`Created by: ${typelitUser('author')}`;
user({ author: { id: 123, name: 'Alice' } }); // "Created by: #123 Alice"

Without a custom stringify function, createType uses JavaScript's built-in String() function to convert values to strings. This is equivalent to:

createType<T>({ stringify: String });

You might want to provide a custom stringify function when:

  • Formatting dates in a specific way
  • Formatting numbers (currency, percentages, fixed decimal places)
  • Creating a custom string representation for objects
  • Adding prefixes, suffixes, or other decorations to values
  • Internationalizing or localizing output

Contributing

We welcome contributions! Please see our Contributing Guide for details on how to set up the development environment and our contribution process.

License

Copyright 2024 Charles Francoise

Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at

http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.