flick-dev
v0.3.1
Published
Design QA on your running app: measure, edit and align against your tokens, or talk through the page, and copy it all as a prompt for your coding agent.
Maintainers
Readme
Flick
Design QA on your running app, written up as prompts for your coding agent.
Flick adds a small toolbar to your app in development. Measure spacing, tweak a component, fix the grid, or talk through the page while you point at things. Every change comes out as a prompt that names the file, the component and the class to change, so your agent (Claude Code, Cursor, Copilot…) can apply it without guessing.
Contents
Install
npm install --save-dev flick-dev
# or
pnpm add -D flick-dev
# or
yarn add -D flick-devQuick start
React
import { Flick } from 'flick-dev/react';
export default function App() {
return (
<>
<YourApp />
<Flick />
</>
);
}<Flick /> loads the toolbar with a dynamic import in development only. In production it's a 0.6 KB wrapper that renders nothing and never fetches the rest.
Next.js (App Router)
<Flick /> is a client component, so you can drop it straight into a server layout.
// app/layout.tsx
import { Flick } from 'flick-dev/react';
export default function RootLayout({ children }: { children: React.ReactNode }) {
return (
<html lang="en">
<body>
{children}
<Flick />
</body>
</html>
);
}Vue
<script setup lang="ts">
import { onMounted, onBeforeUnmount } from 'vue';
import { initFlick, type FlickInstance } from 'flick-dev';
let flick: FlickInstance | null = null;
onMounted(() => (flick = initFlick()));
onBeforeUnmount(() => flick?.destroy());
</script>Anything else
import { initFlick } from 'flick-dev';
const flick = initFlick(); // null in production and during SSRFlick renders inside a shadow root, so its styles never leak into your app and yours never leak into it.
Tools
| Tool | What it does |
| --- | --- |
| Outline | Boxes every element by level (atoms, molecules, organisms) and draws the keylines and baselines things should share. |
| Inspect | Size, padding, margin and gaps of whatever you hover. Click an element to edit it. |
| Edit | Toggle classes or slide spacing, radius, type and color through your own scale. Edits preview live and apply to the whole component, one variant, or one instance. |
| Measure | Distances between two elements, with edge rulers and guides that snap. Hold ⌥ for a quick measure. |
| Columns | Your column grid and baseline, auto-detected, with manual overrides. |
| Grid | A faint 8px square grid, to check things are built on it. |
| Align | Proposes the fixes that put a component or the page on your 8px grid. You see a before/after score, and only the fixes that measurably help are kept. |
| Record | Talk and draw on the page. Each sentence becomes a note tied to the element you meant. |
| Copy to agent | Copies the selected element's specs, or all your pending changes, as a prompt. |
Every value reads in px plus the token it matches (16 · space-4), and anything off your scale is flagged. Flick reads your --space-* CSS variables, the Tailwind scale, or tokens you pass in.
Copy to agent
Select an element and press Copy to agent. You get markdown like this, ready to paste:
## `form.form-row`
- **size:** 1136 × 109.2
- **padding:** 22 ⚠ off-scale (all sides)
- **display:** flex · gap: 13 ⚠ off-scale
- **radius:** 12pxWith edits pending, it copies those instead: each change with its file, component and the exact class string to swap (p-5 → p-6). flick.copySpecs() and flick.copyChanges() do the same from code.
Record feedback
Press Record and talk through the page while you use it. Hold D to draw (or turn on Pen): circle what you mean, or draw a line to where something should go. When you stop, you get a list of moments, each one what you said plus the element you circled, clicked or pointed at. Fix any misheard words, pick how much detail to include, and copy.
## 1 · 0:04 · StatCard › div.card
> "These feel cramped, the number is crashing into the label."
Circled:
- **StatCard › p.stat-value** "$24" (`src/components/StatCard.tsx` · `div.card > p.stat-value`)
- 120 × 32 · font 28/32 600The output is text, not video: a few hundred tokens your agent can act on. Screenshots are optional; turn them on and they download as a zip alongside the prompt, one per moment, with your drawing in it.
Privacy
Speech is transcribed on your device, in any modern browser, and your voice never leaves it. The first time on a site, Flick downloads the speech model (about 100 MB, then cached). English only for now.
The runtime (transformers.js, from jsDelivr) and two open models from Hugging Face: Whisper base.en to transcribe and Silero VAD to hear where sentences end. Nothing about you or your app is sent.
To host the files yourself, pass record: { runtimeUrl, wasmPaths, modelHost }. Otherwise your Content Security Policy needs cdn.jsdelivr.net, huggingface.co and *.hf.co in script-src and connect-src, blob: in worker-src, and 'wasm-unsafe-eval'.
Outline and Align
Flick reads every page as atomic design, from signals any page has. No component names or conventions needed.
Outline draws that structure the way a designer checks alignment: boxes by level, keylines where content starts, baselines across matching cards, and the optical center where an icon meets its label. Anything 1px off is tagged.
Align works top-down on the selection or the page. Its goal is that things are built in multiples of 8 and that what belongs together lines up. It changes values, never positions, and checks its own work: each fix is applied, measured again, and only kept if it helped. Fixes use tokens from your scale and target the shared definition (the component, not one element), so the prompt you copy fixes the source.
Shortcuts
| Key | Action |
| --- | --- |
| ⌥ / Alt (hold) | Measure from whatever you hover |
| D (hold, while recording) | Draw on the page |
| [ or Shift+Enter | Select the parent element |
| ] or Enter | Go back down to the first child |
| Esc | Clear the selection; press again to turn everything off |
There are no single-letter shortcuts, so Flick never takes a key from your app. shortcuts={false} turns these off.
API
Options
Pass them as props to <Flick /> or as an object to initFlick().
| Option | Type | Default | Description |
| --- | --- | --- | --- |
| tokens | Array<'css-vars' \| 'tailwind' \| { name, px }> | ['css-vars', 'tailwind'] | Spacing tokens values are matched against. |
| alignGrid | { base?: number; half?: number } | { base: 8, half: 4 } | The grid Outline checks and Align snaps to. |
| grid | { columns, gutter, margin, maxWidth, baseline } | auto-detected | Manual column grid, merged over detection. |
| initial | { layers?, pointerMode? } | nothing on | What's active when Flick mounts. |
| record | boolean \| { runtimeUrl?, wasmPaths?, modelHost? } | true | false hides Record. The object self-hosts the speech files. |
| theme | FlickThemeInput | orange | Colors and font, deep-merged over defaultTheme. |
| persist | boolean | true | Remember state per page in localStorage. |
| force | boolean | false | Mount in production too, e.g. on a staging build or docs site. |
| ignore | string | none | CSS selector of elements Flick should skip. |
| shortcuts | boolean | true | Esc and the element keys. |
Instance
initFlick() returns a FlickInstance, or null in production and during SSR.
| Method | |
| --- | --- |
| toggle(id, on?) | Turn a tool on or off: 'outline', 'grid' (Columns), 'pixel' (Grid), 'inspect', 'measure'. |
| clear() | Turn everything off. |
| copySpecs() | Copy the selected element's specs. Resolves to the markdown. |
| copyChanges() | Copy all pending edits as a prompt. Resolves to the markdown, or null. |
| align() | Open Align for the selection, or the page. |
| record() / stopRecording() | Open Record, or stop and open the review. |
| destroy() | Remove Flick from the page. |
Types ship with the package.
Requirements
- Desktop Chrome, Edge, Firefox, Safari, or a Chromium-based browser like Dia. Flick is built for pointer and keyboard, not touch.
- React 17 or later for
flick-dev/react(optional; the core works without React). - Record needs a microphone and a secure page (
httpsorlocalhost).
License
Product license under PolyForm Shield 1.0.0. See LICENSE.
© 2026 NOT FOUND.
