Skip to content

dmoptimal/tightset

Repository files navigation

tightset logo

tightset

Variable-weight text fitting engine. Fill any rectangle with kinetic typography.
Live demo →

Every line stretches to fill the width, with heavier weight on larger lines. Works with any variable-weight font. Ships with React, Svelte, Vue, Angular, vanilla Canvas, and DOM/Tailwind renderers.

Install

npm install tightset

Quick Start

import { fit } from 'tightset'
import { render } from 'tightset/canvas'

await document.fonts.ready // always wait for fonts before canvas rendering

const result = fit('Every Line Fills The Width', {
  width: 800,
  height: 500,
  fontFamily: 'Inter',
})

render(document.querySelector('canvas'), result, {
  fontFamily: 'Inter',
  color: '#ffffff',
  background: '#0d0d0d',
})

Font loading: Canvas mode measures text via the Canvas 2D API, so the font must be fully loaded before calling fit(). Wait for document.fonts.ready or use the CSS Font Loading API. The framework components (tightset/react, tightset/vue, etc.) use canvas internally — ensure your fonts are loaded before they mount, or trigger a re-render once fonts are ready.

Packages

Import What
tightset Core engine: fit(), clearCache(), setMeasureContext()
tightset/canvas Canvas 2D draw() and render()
tightset/dom renderToHTML(), renderToDOM(), getLineStyles() — for Tailwind/CSS
tightset/react <Tightset> React component
tightset/svelte <Tightset> Svelte component
tightset/vue <Tightset> Vue component
tightset/angular <TightsetComponent> Angular standalone component

React

import { Tightset } from 'tightset/react'

<Tightset
  text="Make It Tight"
  width={800}
  height={500}
  fontFamily="Inter"
  color="#fff"
  background="#000"
/>

Svelte

<script>
  import Tightset from 'tightset/svelte'
</script>

<Tightset
  text="Hello World"
  width={800}
  height={500}
  fontFamily="Inter"
  color="#fff"
  background="#000"
/>

Vue

<script setup>
import Tightset from 'tightset/vue'
</script>

<template>
  <Tightset
    text="Hello World"
    :width="800"
    :height="500"
    fontFamily="Inter"
    mode="html"
  />
</template>

Angular

Note: The Angular component is shipped as TypeScript source (not pre-compiled), so it cannot be consumed directly from node_modules with AOT compilation. Copy the component into your project from node_modules/tightset/dist/angular/tightset.component.ts, or use the source from src/angular.

// Copy tightset.component.ts into your project, then:
import { TightsetComponent } from './tightset.component'

@Component({
  standalone: true,
  imports: [TightsetComponent],
  template: `
    <tightset
      text="Make It Tight"
      [width]="800"
      [height]="500"
      fontFamily="Inter"
      color="#ffffff"
      background="#0d0d0d"
    />
  `,
})
export class MyComponent {}

Tailwind / DOM

import { fit } from 'tightset'
import { renderToHTML } from 'tightset/dom'

const result = fit('Style Me', { width: 800, height: 400, fontFamily: 'Inter' })
const html = renderToHTML(result, {
  fontFamily: 'Inter',
  containerClass: 'bg-black rounded-2xl',
  lineClass: 'tracking-tight drop-shadow-lg',
})

Or get style objects for JSX:

import { getLineStyles } from 'tightset/dom'

const styles = getLineStyles(result, { fontFamily: 'Inter' })
result.lines.map((line, i) => <div style={styles[i]} className="drop-shadow-lg">{line}</div>)

Options

Option Default Description
width Box width (px, required)
height Box height (px, required)
fontFamily 'sans-serif' Font family name
padX 60 Horizontal padding
padY 40 Vertical padding
gap 20 Line gap
maxWeight 900 Heaviest font weight
spread 150 Weight range (heavy − light)
maxLines 8 Max lines
uppercase true Uppercase transform

Node.js / SSR

import { createCanvas } from 'canvas'
import { setMeasureContext, fit } from 'tightset'

setMeasureContext(createCanvas(1, 1).getContext('2d'))
const result = fit('Server Side', { width: 800, height: 400 })

Demo

Live demo → dmoptimal.github.io/tightset

Or run locally:

npx serve .
# Open http://localhost:3000/docs/

License

MIT

Releases

No releases published

Packages

 
 
 

Contributors