Skip to main content
skill Claude Code CX Codex Cursor GitHub Copilot

better-writing — Claude Code skill: what it does, how to install

Writes and reviews UI copy, from button labels to errors and empty states. It keeps product vocabulary consistent and guides users to the next step.

Install into Claude Code · Skills CLI (Vercel) All methods and platforms ↓
npx skills add jakubkrehel/skills --skill better-writing -a claude-code
Open on GitHub

What better-writing does

The skill drafts and audits interface copy against the existing codebase. It begins by locating translation calls such as t(, <FormattedMessage, or $t( and cataloging terms in locale files like locales/**/*.json or messages/*.json. This inventory prevents synonym drift. If an action is named "Archive" in navigation, it will not turn into "Move to storage" inside a toast.

String concatenation around variables is barred because grammatical word order varies across languages. Plurals and numbers rely on Intl formatters instead. The guidelines enforce verb-first buttons, setting labels that describe the ON state, and error messages that explain how to resolve the issue without blame or exclamation points. Destructive confirmations require explicit consequence descriptions rather than generic questions.

Its scope stops at the text itself. Visual truncation and smart punctuation belong to better-typography, while accessible markup and name attributes are delegated to better-accessibility.

What it helps with

  • eliminate synonym drift across buttons, toasts, and menus
  • rewrite cryptic errors into actionable instructions next to form fields
  • build informative empty states with a direct next step
  • convert variable-concatenated strings into localized templates with Intl

Example prompts for the agent

  • Review the copy in the account deletion modal according to better-writing rules
  • Write an empty state for the invoices view with an action button
  • Check error strings in this checkout form to ensure they provide clear recovery steps

How to install better-writing

1Skills CLI (Vercel)

npx skills add jakubkrehel/skills --skill better-writing -a claude-code

2Manually: put the files in place

~/.claude/skills/better-writing/SKILL.md

Copy the whole skill folder; for one project use .claude/skills/better-writing/

From the same set10

The whole set →
better-ui jakubkrehel This skill sets concrete rules for surface details, icons, shadows, and motion. Use it to polish an interface after its underlying interactions work. Claude Code CX Codex Cursor +1 38,900installs better-typography jakubkrehel Reviews interface typography and applies fixes through the project’s styling system. Use it to check text hierarchy, wrapping, truncation and punctuation. Claude Code CX Codex Cursor +1 33,800installs better-colors jakubkrehel Audits color systems, generates ramps, and maps semantic tokens to roles. Use it when hardcoded hex values pile up or text contrast needs verifiable measurement. Claude Code CX Codex Cursor +1 32,200installs better-layout jakubkrehel A skill that sets grouping, alignment, reading order and responsive structure, then stress-tests the result by resizing, translating and mirroring it for RTL. Claude Code CX Codex Cursor +1 30,400installs better-interface jakubkrehel Runs a cross-discipline interface review covering accessibility, layout, copy, typography, color, and UI polish into one ranked report. Claude Code CX Codex Cursor +1 29,700installs better-accessibility jakubkrehel Reviews an interface against WCAG 2.2 and fixes issues in the project’s styling system. Use it to check keyboard navigation and screen-reader behavior. Claude Code CX Codex Cursor +1 29,200installs interface-review jakubkrehel Audits pull requests, branches, and uncommitted edits for layout, UI, accessibility, and typography regressions. Keeps focus on what changed rather than pre-existing debt. Claude Code CX Codex Cursor +1 18,100installs explain-interface jakubkrehel Explains how a visual effect, animation, or website layout was built from a live page or a screenshot. It breaks down the underlying layer stack. Claude Code CX Codex Cursor +1 13,900installs

Similar

vue Anthony Fu This skill guides agents through Vue 3 Composition API, script setup, and reactivity. Use it when writing Vue SFCs or built-in component flows. Claude Code CX Codex Cursor +1 35,800installs game-engine official github Guides GitHub Copilot when building browser games and game engines with HTML5 and JavaScript. Use it for 2D or 3D rendering, physics, collisions, and controls. GitHub Copilot 13,140installs flags react This skill runs React's feature-flag command and explains the results. Use it to compare release channels when a feature behaves differently between them. Claude Code CX Codex Cursor +1 1,100installs flow react Runs Flow type checking in a React project and reports errors with file locations. Useful when you edit code and don't want to look up the right renderer flag each time. Claude Code CX Codex Cursor +1 1,100installs frontend-design official anthropics This skill guides intentional visual design for new interfaces and redesigns. Use it when a generic generated UI is not enough. Claude Code Claude.ai 1,025,790installs design-taste-frontend Leonxlnx This skill directs the design of public pages and work screens, then checks the result in a browser through screenshots. Use it when an interface feels generic or unfinished. Claude Code CX Codex Cursor +1 673,100installs prototype Matt Pocock Creates throwaway prototypes for checking state logic or exploring UI before committing the decision to the main codebase. Claude Code 986,201installs hyperframes heygen-com Instructs coding agents on creating, validating, and rendering HTML-based videos using the HyperFrames framework and CLI. Claude Code CX Codex Cursor +1 1,200,000installs

Questions about better-writing

How to install better-writing in Claude Code?

Run npx skills add jakubkrehel/skills --skill better-writing -a claude-code in your terminal. You can also place the file directly at ~/.claude/skills/better-writing/SKILL.md.

What does the better-writing skill do?

It audits and writes UI copy like labels, empty states, and confirmations. The skill ensures terminology stays consistent with the existing codebase and prevents dead ends for users.

Does better-writing handle UI layout and accessibility attributes?

No. It handles wording, tone, and sentence structure. Truncation and typography belong to better-typography, layout space belongs to better-layout, and accessible names belong to better-accessibility.

Source text

SKILL.md · MIT
---
name: better-writing
description: Writes and reviews interface copy, from labels and errors to empty states and confirmations, so it matches the product's voice and tells people what to do next.
---

# Writing

This skill writes and reviews interface copy such as labels, errors, empty states and confirmations, along with the terms that run through them. It matches the product's existing voice and flags copy that misleads people or leaves them without a way forward.

A deliberate brand voice is not a defect. Raise a departure from plain language only when it creates inconsistency, ambiguity, translation risk or a tone the stakes don't support. Rewording that merely suits your taste is not a finding.

How copy renders, including `text-transform`, truncation and smart punctuation, belongs to `better-typography`. Error markup, announcements and the attributes that carry accessible names belong to `better-accessibility`. Room for translated strings belongs to `better-layout`.

## Inventory the existing strings first

Before writing or reviewing, find where the copy lives and read the copy around the change:

1. Search for the translation call (`t(`, `i18n.`, `<FormattedMessage`, `$t(`) and the locale files it reads, such as `locales/**/*.json`, `messages/*.json`, `*.po` and `*.strings`. Copy may also come from a CMS or the API.
2. List the noun used for each object and the verb used for each action, as in "project" or "workspace" and "Delete" or "Remove".
3. Note the case used per element type and any voice or content style guide.

New copy uses the terms on that list. A synonym is a finding only where the same thing is named two ways.

## One voice, one vocabulary

The product has one voice and its existing copy establishes it. A local edit does not get to invent a new one. If it's "Archive" in the menu, it isn't "Move to storage" in the toast.

A multi-step flow uses one vocabulary throughout: "Get started" to enter, either "Continue" or "Next" to advance, "Done" to finish. Tone flexes with the stakes:

| Context | Tone |
| --- | --- |
| Success, onboarding, empty states | Warm, can be light |
| Routine actions, settings | Neutral, minimal |
| Errors, destructive confirmations | Calm, plain, zero playfulness |
| Data loss, security | Serious, explicit |

## Address the reader directly

In instructional copy, write "you", not "the user". In errors, "we" reads as deflection, so prefer "Unable to load content. Check your connection and try again." An established first-person voice can stay in low-stakes copy where it still reads clearly.

Use possessives sparingly: "Favorites" beats "Your favorites". Never mix perspectives in one flow, such as "My account" beside "Your settings".

## Plain words over clever ones

Choose words a tired reader gets on the first pass, and delete every word that does no work. No idioms, no colloquialisms and no humor that won't translate.

Skip unnecessary gender: "Subscribers can post recipes", not "each subscriber can post his or her recipes". Match the input device: "tap" on touch, "click" with a pointer, "select" when both are possible.

## Build strings whole

Never assemble a sentence from fragments around a variable (`"You have " + n + " new messages"`), because word order changes per language. Write one message with placeholders, and use the locale's plural rules rather than `n === 1 ? "" : "s"`. Many languages have more than two plural forms. Format numbers, dates and lists through `Intl`. Recipes are in [patterns.md](patterns.md#plurals-and-placeholders).

## Verb-first buttons

A button label starts with a verb naming the action: "Send", "Save draft", "Delete project". Never "OK!" or "Let's go!".

An icon-only button's accessible name follows the same rule. It names the action, "Delete project", never the glyph, "Trash icon". The attribute that carries it is `better-accessibility`'s.

## Links describe their destination

Link text makes sense out of context, because screen-reader users navigate by a list of the page's links. Write "Read the billing docs", never "Click here".

A bare "Learn more" breaks down as soon as two appear on one page. Suffix each one: "Learn more about exports".

## One capitalization policy

Pick title case or sentence case per element type, then apply it to every instance of that type. Sentence case is the default where the project has no policy. "Save Changes" beside "Discard changes" reads as sloppiness.

## Settings describe the ON state

Label a toggle for what happens when it is on. "Send read receipts" lets users infer the off state; "Don't send read receipts" turns the toggle into a double negative.

Link straight to a referenced setting rather than describing the path to it: a "Notification settings" link, not "Go to Settings > Notifications > Email".

## Errors say how to fix, next to where it broke

An error is an instruction, and it belongs beside the field that failed:

| Bad | Good |
| --- | --- |
| That password is too short | Choose a password with at least 8 characters |
| Invalid date | Enter a date as DD/MM/YYYY |
| Oops! Something went wrong. | Unable to save. Check your connection and try again. |

No blame, no "oops" and no exclamation marks. Phrase hints positively, as in "Use at least 8 characters" rather than "Don't use fewer than 8". Show a known requirement as helper text before input, not only in the error. When the same error keeps firing, redesign the interaction so it cannot happen.

## Undo beats confirmation

Prefer undo when the action can be reversed and people perform it often, such as archiving, moving or deleting into a trash. Act at once and offer undo in the result: "Project archived. Undo".

Confirm before acting when the action cannot be reversed, affects other people or destroys many items at once. The confirmation repeats the consequence, so the dialog is answerable without reading the body:

- The title names the action and the object, "Delete 'Q3 report'?", never "Are you sure?".
- The body says what is lost and what cannot be recovered, with counts where they apply.
- The buttons are verb plus object, `Delete project` and `Cancel`, never `Yes` and `No`.
- For an account, a workspace or a repository, ask the person to type the object's name.

Templates are in [patterns.md](patterns.md#destructive-flows). The destructive button's distinct color is `better-colors`'.

## Empty states point forward

An empty state says what this place is and how to fill it, and offers one clear next action:

```html
<!-- Bad: a shrug -->
<p>No results.</p>

<!-- Good: orientation plus a next step -->
<p class="font-medium">No projects yet</p>
<p class="text-sm text-zinc-500">Projects keep your tasks and files together.</p>
<button class="mt-4">Create a project</button>
```

A filtered empty state names the query and offers an exit: "No results for 'quarterly'. Clear filters". Never park persistent information in an empty state. It disappears the moment content exists.

Loading, saving and success copy is in [patterns.md](patterns.md#status-copy).

## Placeholders show an example

A placeholder shows a realistic example in the format the field accepts, `[email protected]` or `DD/MM/YYYY`, never an instruction. Whether the field also needs a visible label is `better-accessibility`'s.

## Before you finish

| Detection pattern | Fix |
| --- | --- |
| `Click here`, a link reading `here` or two identical `Learn more` links | Name the destination |
| `Oops`, `Something went wrong` or `!` in an error string | Say what failed and the next step |
| `" + n + "`, a template literal holding a sentence fragment, or `=== 1 ? "" : "s"` | One ICU message with a plural argument |
| `>OK<`, `>Yes<` or `>No<` on a dialog button | Verb plus object |
| `Are you sure` | Name the action and the object |
| `successfully` | Cut it: "Changes saved" |
| `Please` in a routine instruction | Cut it |
| A toggle label starting `Don't`, `Disable` or `Hide` | Describe the ON state |
| `aria-label="Trash"`, `"Close icon"` or `"X"` | Name the action: "Delete project", "Close dialog" |
| `toLocaleDateString()` with no locale, or a date built from `getMonth()` | `Intl.DateTimeFormat` with the user's locale |
| `Save Changes` beside `Discard changes` | One case per element type |

## Reporting

**Severity.** `HIGH` misleads the user or hides how to recover from an error. An error that names no way to recover is always `HIGH`, as is a destructive action with neither confirmation nor undo. `MEDIUM` breaks voice, terminology or capitalization consistency. `LOW` is isolated wording polish.

**Verification.** Check every label against the action it invokes, every error for a stated fix and every term against the inventory. Read locale files as well as components. Report strings supplied by the server or a CMS that you could not see as `Not verified`.

**Format.** Group findings under the principle each violates, ordered by severity, one row per root cause listing every location it appears in:

| Severity | Location | Before | After | Why |
| --- | --- | --- | --- | --- |

`Location` is `path/to/file:line`. `Why` names the principle and the user impact.

End with `Block` when any `HIGH` remains, `Approve` otherwise, leaving the rest in the table as work to do. Never `Approve` coverage you did not inspect. With nothing to report, state "No actionable writing findings" and report verification.

© jakubkrehel · MIT · jakubkrehel/skills

See also

Project sponsors

Companies that keep this analytics open
Gold sponsor

Impressions, clicks and code copies — open statistics. We keep the numbers public for the same reason NeBlask itself is public. Become a sponsor