@typefit/core
v1.0.0
Published
Framework-agnostic APIs to make text always fit perfectly.
Readme
@typefit/core
Framework-agnostic Typefit APIs.
@typefit/core contains the Pretext-powered measurement engine and the imperative DOM fitting API.
Use it when you are not using React, when you need measurement results directly, or when you want to
build your own framework binding.
Install
bun add @typefit/corenpm install @typefit/corePure Measurement
fitText returns a layout result without changing the DOM.
import { fitText } from '@typefit/core';
const result = fitText({
text: 'Text that always fits perfectly.',
width: 520,
maxSize: 96,
lines: { target: 2, max: 3 },
strategy: 'balance',
font: { family: 'Inter', weight: 700 },
includeLines: true,
});
if (result.fits) {
console.log(result.fontSize);
console.log(result.lines);
}fitText is useful for canvas rendering, layout previews, tests, and any code path where you want
to inspect the chosen font size before rendering.
DOM Fitting
typefit measures an element, applies the fitted styles, and can keep the element up to date.
import { typefit } from '@typefit/core';
const instance = typefit(document.querySelector('[data-headline]')!, {
maxSize: 96,
lines: { min: 2 },
observe: true,
});
instance.refresh();
instance.update({ shape: 'diamond' });
instance.destroy();When font is not provided, the DOM API reads the computed font styles from the element:
font-familyfont-weightfont-stylefont-stretchfont-sizeline-heightletter-spacingwhite-spacetext-transform
Custom Fonts
Load custom fonts through CSS as usual:
@font-face {
font-family: "Open Runde";
src: url("/fonts/OpenRunde-Semibold.woff2") format("woff2");
font-weight: 600;
font-style: normal;
font-display: swap;
}Then either let typefit read the computed styles:
typefit(element, { maxSize: 96 });Or pass an explicit font shorthand:
typefit(element, {
maxSize: 96,
font: (size) => `600 ${size}px "Open Runde", system-ui, sans-serif`,
});When document.fonts reports a font load, Typefit clears cached text metrics and refits observed
instances.
Browser Support
@typefit/core works in any current browser with standard canvas text measurement. It uses
OffscreenCanvas when available and falls back to a DOM canvas context, so Chromium, Firefox,
WebKit/Safari, and other standards-compliant browsers are supported.
Server-only measurement is not yet a V1 target. Unsupported non-browser environments should call
isSupported() or handle the clear unsupported-runtime error from fitText.
API
| Export | Description |
| --- | --- |
| fitText(options) | Pure measurement API. Requires text, width, and font. |
| typefit(element, options) | DOM fitting API. |
| isSupported() | Returns whether the current runtime can measure text. |
| clearCache() | Clears the Pretext measurement cache. |
| setLocale(locale?) | Sets the segmentation locale used by Pretext. |
Options
| Option | Default | Description |
| --- | --- | --- |
| text | required for fitText | Text to measure. |
| width | required for fitText | Available width in pixels. |
| height | none | Optional height limit in pixels. |
| font | required for fitText | CSS font shorthand, size callback, or font spec. |
| minSize | 10 | Smallest font size Typefit may choose. |
| maxSize | 512 | Largest font size Typefit may choose. |
| lines | none | { min, target, max } line-count policy. |
| strategy | 'balance' | 'balance' or 'fill'. |
| balance | { mode: 'even' } | Wrap scoring options. |
| shape | none | Shape preset or custom rows. |
| snap | none | Allowed font sizes. |
| lastLine | none | Final-line quality constraints. |
| avoidWidows | false | Shortcut for avoiding short final lines. |
| lineHeight | 1.1 | Multiplier or size callback. |
| whiteSpace | 'normal' | 'normal' or 'pre-wrap'. |
| wordBreak | 'normal' | Pretext word-break policy. |
| letterSpacing | none | Letter spacing in pixels. |
| precision | 0.25 | Binary-search precision in pixels. |
| includeLines | false | Include measured line data in the result. |
Result
type FitTextResult = {
fits: boolean;
fontSize: number;
scale: number;
lineHeight: number;
lineCount: number;
width: number;
height: number;
wrapWidth: number;
strategy: 'balance' | 'fill';
reason: 'fit' | 'height' | 'last-line' | 'max-lines' | 'min-lines' | 'width';
reasons: Array<'fit' | 'height' | 'last-line' | 'max-lines' | 'min-lines' | 'width'>;
lines?: Array<{ text: string; width: number; availableWidth: number; x: number }>;
};Contributing
We would love to have your help in making Typefit better.
Here's how you can contribute:
- Report a bug you found while using Typefit
- Request a feature that you think would be useful
- Submit a pull request if you want to contribute with new features or bug fixes
License
Typefit is licensed under the MIT License.
