tynix

Brand

This page is the source of truth for how tynix looks and sounds. The tokens on this page are implemented in docs/.vite/brand.ts, and the asset files live in docs/public/brand/. Change both together.

Positioning

Gradual types for Nix. Add types where they help, keep the rest dynamic, and ship plain .nix with zero runtime.

tynix is for people who already write Nix and are tired of finding attribute typos at evaluation time. It takes the approach TypeScript took with JavaScript: an optional, gradual, structural type layer with first-class editor support, which compiles away completely.

Aspect Description
Category gradual type system and toolchain for Nix
Audience Nix users maintaining flakes, packages, modules and shared libraries
Promise catch shape errors before evaluation, without changing what Nix runs
Proof points erasure-only compiler, structural records, .d.tynix declarations, LSP, stable diagnostic codes
Not a new Nix, a runtime contract system, or a replacement for the module system's option types

Taglines

  • Headline: Gradual types for Nix.
  • Supporting line: Add types where they help, keep the rest dynamic, and ship plain .nix with zero runtime.
  • Short: Type your Nix. Ship plain Nix.

Use the headline with the supporting line on the home page, the README and the OG image, and the headline alone in package descriptions and page titles. The short one fits badges, social bios and slide footers. "TypeScript-like" is fine as a comparison in body copy that explains the approach; it is not a tagline.

Voice and tone

tynix speaks like a careful senior engineer reviewing your pull request: precise, calm, and on your side.

  • Concrete over clever. Show the code and the exact diagnostic. "Selecting pkg.pname from an unannotated parameter fails with TC0009" beats "tynix catches tricky bugs".
  • Honest about limits. Say what is not supported yet and what to do instead. Mark upcoming features as upcoming.
  • Respect Nix. tynix adds to Nix; it does not fix it. Never frame Nix as broken or tynix as a replacement.
  • Short sentences, active voice, second person. "Annotate the parameter", not "the parameter should be annotated by the user".
  • No hype words. Avoid "blazing", "magical", "revolutionary", "seamless". Measurable claims only.
  • Diagnostics are part of the voice. Error messages state what was found and what was expected, in that order, with the code first: [TC0013] type mismatch: 42 vs String.

Name usage

  • The name is always lowercase tynix, including at the start of a sentence and in titles: "tynix checks records structurally."
  • Never TyNix, TYNIX, Ty-Nix or Tynix. Not abbreviated, not pluralized.
  • Pronounce it "tie-nix": typed Nix.
  • In running text, use plain tynix. Use code formatting (`tynix`) only when you mean the command or the binary.
  • File types are written with their dot: .tynix, .d.tynix, .nix.
  • Nix is capitalized when you mean the language or package manager, as the Nix project does.

The mark brings together the two languages tynix sits between:

  • Nix: six lambdas interlock into a hexagonal ring, after the Nix lambda snowflake. They are woven, each lying over the next, so the ring has no start or end.
  • Haskell: every stroke is cut flat, like the slanted bars of the Haskell logo, and the arms alternate Nix blues with Haskell purples.
  • tynix: the ring holds ::, the type annotation tynix shares with Haskell, drawn as two slanted bars in Annotation Amber, the color the docs use for erased type syntax.

The geometry lives in scripts/generate-brand.ts; edit it there and run vp run generate:brand to regenerate every SVG and PNG below.

tynix logo, color, for light backgrounds
tynix-logo.svg
tynix logo, color, for dark backgrounds
tynix-logo-dark.svg
tynix logo, single color ink
tynix-logo-mono.svg
tynix logo, single color white
tynix-logo-white.svg
tynix mark, color
tynix-mark.svg
tynix mark, color, for dark backgrounds
tynix-mark-dark.svg
tynix mark, white
tynix-mark-white.svg
tynix app icon
tynix-app-icon.svg
File Use
brand/tynix-logo.svg default lockup on light backgrounds
brand/tynix-logo-dark.svg lockup on dark backgrounds
brand/tynix-logo-mono.svg, brand/tynix-logo-white.svg one-color print, embossing, single-color UIs
brand/tynix-mark.svg, brand/tynix-mark-dark.svg the mark alone on light / dark backgrounds
brand/tynix-mark-mono.svg, brand/tynix-mark-white.svg one-color mark
brand/tynix-app-icon.svg the mark on its ink tile: app icons, the docs header, the favicon
brand/tynix-wordmark.svg the wordmark alone, where the mark already appears nearby
brand/tynix-mark-512.png raster app icon for places that do not accept SVG
favicon.svg, apple-touch-icon.png browser and home-screen icons
og-image.png (source brand/og-image.svg) 1200 × 630 social preview

Rules:

  • Keep clear space around the logo of at least one stroke width on all sides. Do not place it on busy imagery.
  • Minimum size: 16 px for the app icon, 24 px for the bare mark, 20 px tall for the lockup.
  • Do not recolor, rotate, outline, add shadows to, or re-typeset the wordmark. The wordmark is drawn, not set in a font; use the files.
  • On photos or saturated backgrounds, use the white one-color version.

Color

The palette comes straight from the mark. Nix blues carry links, buttons and focus; Haskell purples appear in the mark, the hero glow and "important" callouts. Annotation Amber has one job: it marks type-only syntax, everything the compiler erases. Surfaces are cool neutrals around the mark's ink tile, never cream or pure black.

Core

Nix Blue#5277C3
Nix Deep#3F65B5
Nix Deeper#2F4F96
Snow Blue#7EBAE4
Haskell Purple#5E5086
Haskell Magenta#8F4E8B
Haskell Ink#453A62
Annotation Amber#F2B441
Amber 700#8A5A00

Neutrals

Ink 950#0A0E1A
Ink 900 (tile)#0E1424
Ink 850#131B2E
Ink 700#27324B
Slate 600#505B74
Slate 300#9AA6BF
Line#DCE1EB
Mist#EDF0F6
Paper#F7F8FB

Theme tokens

Token Light Dark
primary Nix Deep #3F65B5 #93B4EE
primaryHover Nix Deeper #2F4F96 #B9CEF5
background Paper #F7F8FB Ink 950 #0A0E1A
backgroundAlt Mist #EDF0F6 Ink 850 #131B2E
text #141A2B #E4E9F4
textMuted Slate 600 #505B74 Slate 300 #9AA6BF
border Line #DCE1EB Ink 700 #27324B
codeBackground Ink 900 #0E1424 Ink 900 #0E1424

The home page hero and the closing call to action sit on an Ink 900 band in both schemes, the same tile the app icon uses. Its primary button is Annotation Amber with Ink 950 text.

Contrast

All text pairings meet WCAG 2.2 AA (4.5:1 for body text); most meet AAA.

Pair Ratio
text #141A2B on Paper 16.31:1
Slate 600 on Paper 6.40:1
Nix Deep on Paper (links) 5.29:1
white on Nix Deep (buttons) 5.61:1
Amber 700 on Paper 5.58:1
#E4E9F4 on Ink 950 15.83:1
Slate 300 on Ink 950 7.87:1
#93B4EE on Ink 950 (dark-mode links) 9.17:1
Ink 950 on Annotation Amber (hero button) 10.43:1
Annotation Amber on Ink 900 (code) 9.95:1
comment #7482A0 on Ink 900 (code) 4.76:1

Annotation Amber is for dark surfaces. On light surfaces, use Amber 700 #8A5A00 for text.

Typography

Role Typeface Fallback stack
Headings and the hero Bricolage Grotesque 600 to 800 IBM Plex Sans, system-ui, sans-serif
UI and prose IBM Plex Sans 400, 500, 600, italic 400 system-ui, -apple-system, Segoe UI, sans-serif
Code JetBrains Mono 400, 500, 600 ui-monospace, SF Mono, Menlo, Consolas, monospace

All three are open source (SIL OFL) and served from Google Fonts on the docs site. Bricolage Grotesque gives headings a little of the mark's cut-stroke character; it is set at 700 to 800 with tight tracking (-0.025em to -0.05em as size grows). Body text is IBM Plex Sans 400 at 16 px with a 1.7 line height and a measure of about 46 rem. Code is JetBrains Mono at 13 px without ligatures, so -> and :: read exactly as typed. The wordmark is custom drawn and is not set in any of these.

Code theme: tynix ink

Code blocks are always Ink 900 so the semantic colors work the same in both site themes. The theme, tynix ink, follows one idea: amber is for anything the compiler erases. The other colors come from the mark: purples for keywords, blues for names and values.

Token Color
type-only syntax: ::, type, declare, forall, extends, infer, as, type names Annotation Amber #F2B441
gradual types: dynamic, unknown, any Annotation Amber, italic
keywords: let, in, if, with, rec, inherit, import #C4ABF0
strings and paths #93D6B5
attribute names, numbers, true, false, null #93B8F2
lambda parameters #E6B3DD
comments #7482A0, italic
# @tynix-ignore / # @tynix-expected Snow #A9D3F0, semibold
operators and punctuation #8C97B2
plain text #D6DDEC

The colors are Ox Content theme tokens (--octc-syntax-*), so blocks the built-in highlighter paints (nix, bash, json, yaml, ts) use the same palette.

tynix
type Package = { pname :: String; version :: String; };

let
  # @tynix-ignore
  describe = (pkg :: Package): "${pkg.pname}-${pkg.version}";
  hello = { pname = "hello"; version = "2.12.1"; } as Package;
in describe hello

The TextMate grammar used for docs highlighting lives in docs/.vite/tynix-grammar.ts, and docs/.vite/highlight.ts applies it after the site is built. Editors get semantic highlighting from the language server instead.

Imagery and layout

  • Hexagons, the colon and thin connector lines are the recurring motifs. Use them sparingly as structure (backgrounds, diagrams), never as decoration on top of content.
  • Diagrams use the theme's surface colors with Nix blue for "process", Amber for "type-level" and Haskell purple for "output".
  • Prefer real code and real diagnostics over illustrations.