@blurwind/core
v0.4.0
Published
Framework-agnostic build-time engine for generating LQIP blur placeholders.
Maintainers
Readme
@blurwind/core
Framework-agnostic, build-time engine for generating LQIP blur placeholders.
@blurwind/core scans your source for image references, loads each image
(remote CDN or local disk), turns it into a tiny blurred data: URI via a
pluggable strategy, and writes a deterministic manifest. It imports no
framework and only depends on sharp.
Most apps drive this through @blurwind/cli. Use the programmatic API
directly when you need a custom pipeline or your own strategy.
Install
pnpm add -D @blurwind/coreProgrammatic usage
import { createGenerator, resolveConfig } from '@blurwind/core'
const config = resolveConfig({
scanDir: 'app',
baseURL: process.env.ASSET_CDN_PATH,
output: { dir: 'app/constants', file: 'blur-data.ts' }
})
const result = await createGenerator(config).run()
// { found, generated, reused, failed, written, durationMs }Configuration
resolveConfig(user) fills every gap with a default. All fields are optional.
| Option | Type | Default |
| --- | --- | --- |
| scanDir | string \| string[] | 'src' |
| ignoreDirs | string[] | node_modules, .next, .git, dist, build, … |
| extensions | RegExp | /\.(tsx?\|jsx?\|mjs\|cjs\|mdx?\|astro\|vue\|svelte\|html)$/ |
| match | RegExp | broad image-URL / path matcher |
| baseURL | string | '' (falls back to $BLURWIND_BASE_URL) |
| publicDir | string | 'public' (used when baseURL is empty) |
| strategy | string | 'blur' |
| blur | { size, radius, format, quality } | { 10, 1.5, 'webp', 40 } |
| fetch | { attempts, backoffMs, timeoutMs?, headers? } | { 3, 1000 } |
| output.dir | string | 'src/generated' |
| output.file | string | 'blur-manifest.ts' |
| output.formats | ('ts' \| 'json')[] | ['ts'] |
| output.tsExportName | string | 'BLUR_DATA_URLS' |
| concurrency | number | 4 |
| cache | { enabled, dir } | { false, node_modules/.cache/blurwind } |
| failSafe | boolean | true |
| logLevel | 'silent' \| 'error' \| 'warn' \| 'info' \| 'debug' | 'info' |
Custom strategies
A strategy receives raw bytes plus an injected sharp factory and returns a
placeholder value. Register it on the generator:
import { createGenerator, resolveConfig, type Strategy } from '@blurwind/core'
const shimmer: Strategy<'shimmer'> = {
name: 'shimmer',
async generate({ sharp, bytes }) {
const { width, height } = await sharp(bytes).metadata()
const svg = `<svg xmlns="http://www.w3.org/2000/svg" width="${width}" height="${height}"/>`
return { value: `data:image/svg+xml;base64,${Buffer.from(svg).toString('base64')}`, width, height }
}
}
await createGenerator(resolveConfig({ strategy: 'shimmer' })).use(shimmer).run()Manifest shapes
ts— a flatRecord<string, string>const (src → data URI). Byte-stable output; zero runtime cost to import.json— the versionedManifest({ version, generatedAt, entries }) with per-entry metadata for tooling.
Read them with @blurwind/runtime's resolvePlaceholder, which
accepts either shape.
License
MIT © Benyamin Khodadadi
