Skip to content
kerfjsGitHub

CodeBlock

A block of coloured code with a copy button.

SourcePackage @kerf-js/veneerTry it

Preview

tsx
import { CodeBlock } from '@kerf-js/veneer'export function Basic() {  return (  <CodeBlock    code={CONFIG}    language="ts"  />  )}const CONFIG =  `import { defineProject } from 'kerf'` +  `export default defineProject({  name: 'storefront',  regions: ['eu-west', 'us-east'],  build: 'npm run build',})`

Installation

npm install @kerf-js/veneer

Try it

Change the controls: the preview and its code update together. The address keeps what you set, so you can link to it.

Live preview
Controls
Language
Codeupdates as you change the controls
import { CodeBlock } from '@kerf-js/veneer'<CodeBlock code={CONFIG} filename="kerf.config.ts" language="ts" lines />

Usage

tsx
import { CodeBlock } from '@kerf-js/veneer'<CodeBlock  code={CONFIG}  language="ts"/>

With a filename

Use filename to show the file's name above the code.

tsx
import { CodeBlock } from '@kerf-js/veneer'export function Filename() {  return (  <CodeBlock    code={CONFIG}    language="ts"    filename="kerf.config.ts"  />  )}const CONFIG =  `import { defineProject } from 'kerf'` +  `export default defineProject({  name: 'storefront',  regions: ['eu-west', 'us-east'],  build: 'npm run build',})`

With line numbers

Use lines to number each line.

tsx
import { CodeBlock } from '@kerf-js/veneer'export function Lines() {  return (  <CodeBlock    code={CONFIG}    language="ts"    lines  />  )}const CONFIG =  `import { defineProject } from 'kerf'` +  `export default defineProject({  name: 'storefront',  regions: ['eu-west', 'us-east'],  build: 'npm run build',})`

Wrapping

wrap breaks long lines. Without it they scroll.

tsx
import { CodeBlock } from '@kerf-js/veneer'export function Wrap() {  return (  <CodeBlock    wrap    language="sh"    code={      'kerf deploy --project storefront ' +      '--region eu-west --region us-east ' +      "--message 'Cache product images at the edge' " +      '--wait'    }  />  )}

Other languages

tsx, ts, js, json and sh are coloured. Anything else stays plain.

tsx
import { CodeBlock } from '@kerf-js/veneer'export function Json() {  return (  <CodeBlock    language="json"    filename="deploy.json"    code={SAMPLE}  />  )}const DEPLOYS = [  {    id: 'd-4821',    project: 'storefront',    branch: 'main',    commit: '9f3ac21',    message: 'Cache product images at the edge',    author: 'Priya Raman',    status: 'Live',    minutes: 2,    at: '2026-10-31T16:42',  },  {    id: 'd-4820',    project: 'search-api',    branch: 'ranking-v2',    commit: '1be07d4',    message: 'Rank exact matches first',    author: 'Lena Fischer',    status: 'Building',    minutes: 6,    at: '2026-10-31T16:10',  },  {    id: 'd-4819',    project: 'mobile-bff',    branch: 'main',    commit: 'c44e190',    message: 'Retry timed out upstream calls',    author: 'Sam Okafor',    status: 'Failed',    minutes: 4,    at: '2026-10-31T15:27',  },  {    id: 'd-4818',    project: 'checkout',    branch: 'main',    commit: '70d2fa8',    message: 'Add Apple Pay to the last step',    author: 'Tomás Oliveira',    status: 'Live',    minutes: 3,    at: '2026-10-31T14:03',  },  {    id: 'd-4817',    project: 'edge-cache',    branch: 'main',    commit: 'e81b6c2',    message: 'Lower the stale window to 30s',    author: 'Jun Tanaka',    status: 'Live',    minutes: 1,    at: '2026-10-31T11:55',  },  {    id: 'd-4816',    project: 'billing',    branch: 'main',    commit: '2ad9e03',    message: 'Prorate seats on plan change',    author: 'Mara Lindqvist',    status: 'Live',    minutes: 3,    at: '2026-10-29T17:20',  },]const SAMPLE = JSON.stringify(DEPLOYS[0], null, 2)

One task, three ways

Pair a Segmented control with CodeBlock to let people pick which version of the code to read.

tsx
import { state } from '@kerf-js/core'import {  CodeBlock,  Segmented,  Stack} from '@kerf-js/veneer'export function Chooser() {  const way = state('ts')  return (    <Stack gap="related">      <Segmented        label="How to deploy"        size="sm"        value={way.value}        onChange={(v) => (way.value = v)}        options={WAYS}      />      {way.value === 'ts' && (        <CodeBlock          code={STACKS.ts}          language="ts"        />      )}      {way.value === 'sh' && (        <CodeBlock          code={STACKS.sh}          language="sh"        />      )}      {way.value === 'json' && (        <CodeBlock          code={STACKS.json}          language="json"        />      )}    </Stack>  )}const STACKS = {  ts:    'const res = await kerf.deploy({ ' +    "project: 'storefront' })" +    '\nconsole.log(res.url)',  sh: `kerf deploy --project storefront`,  json: `{ "project": "storefront" }`,}const WAYS = [  { value: 'ts', label: 'SDK' },  { value: 'sh', label: 'CLI' },  { value: 'json', label: 'API' },]

When to use

Use it for

  • Several lines of code to read or copy

Reach for something else

Accessibility

Tab
Focuses the code, so arrow keys can scroll it
  • Long lines scroll, so the block takes focus for keyboard users.
  • It is coloured on the server and needs no script. copyButtons() from @kerf-js/veneer-core, called once, runs every copy button.

Theming

Restyle it app-wide from veneer() in your kerf config. Every key takes colour, spacing, size, radius, shadow, type and motion; its own keys are listed. A state nests inside: hover: { bg: 'ink' }. Text on a fill you set is contrast-checked at build. How theming works

KeyOwn keysStates
parts.copyradiushover, focus, press, active, open, disabled
ts
veneer({  colors: { brand: '#e8590c', ink: '#1b1b1f' },  parts: {    copy: { radius: 'pill' },  },})

API Reference

PropTypeDefaultDescription
codestring—The source to show, colour and copy.
languagestring'tsx'tsx by default; ts, js, json and sh are coloured too, anything else stays plain.
filenamestring—A file name shown in the bar above the code.
linesbooleanfalseLine numbers.
wrapbooleanfalseWrap long lines instead of scrolling.

Parts

Every element carries a stable name, so you can style it from your own CSS: [data-scope="codeblock"] [data-part="head"]

headfilelang

RelatedSnippetCodeCode inputMarkdown