Lode — a typeface for code

Lode is a monospace typeface for reading and writing code in editors and terminals. Lode is designed for clarity at small sizes on high-resolution screens featuring a very high x-height, thin strokes, slender column widths, open aperatures, and neo-grotesque forms with disambiguating characters.

Lode is a modified variant of the excellent open-source Iosevka.

Download

Lode includes support for dark mode, terminal fixed width, texture healing, and ligatures for common operators and markup.

 !"#$%&'()*+,-./  01234‍56789:;<=>?  U+0020-U+003F
@ABCDEFGHIJKLMNO  PQRSTUVWXYZ[\]^_  U+0040-U+005F
`abcdefghijklmno  pqrstuvwxyz{|}~   U+0060-U+007F

# Bold
 !"#$%&'()*+,-./  01234‍56789:;<=>?  U+0020-U+003F
@ABCDEFGHIJKLMNO  PQRSTUVWXYZ[\]^_  U+0040-U+005F
`abcdefghijklmno  pqrstuvwxyz{|}~   U+0060-U+007F

# Italic
 !"#$%&'()*+,-./  01234‍56789:;<=>?  U+0020-U+003F
@ABCDEFGHIJKLMNO  PQRSTUVWXYZ[\]^_  U+0040-U+005F
`abcdefghijklmno  pqrstuvwxyz{|}~   U+0060-U+007F

# Bold Italic
 !"#$%&'()*+,-./  01234‍56789:;<=>?  U+0020-U+003F
@ABCDEFGHIJKLMNO  PQRSTUVWXYZ[\]^_  U+0040-U+005F
`abcdefghijklmno  pqrstuvwxyz{|}~   U+0060-U+007F

Slender columns

Lode sets a column width grid where 1ch = 0.55em, which is narrower than most monospaced fonts which set 1ch = 0.6em without being a true condensed. This offers a balance of aiding legibility while keeping more columns on your screen.

Hamburgerfonstiv. Lode
Hamburgerfonstiv. Roboto Mono

Disambiguation

Lode aids accuracy and legibility by providing otherwise similar looking characters with unambiguous forms, differentiating tails, and a dotted zero.

!iIlL17|¦  UuvVwWMm   0OQC8BßD¢co
fΓſßoðdþb  $S5Z2zs    G96bgpq¶P
CE3ƷʒЗзξ   -_.,`'"    «»<>←→

Dark mode

When light text appears on a dark background, it can be perceived as slightly bold. The Lode font family includes "Lode Dark" to compensate for this with a slightly thinner stroke weight.

illuminate :: String -> String
illuminate text = map (\char ->
    case char of
        'O' -> '☀'
        'D' -> '◗'
         _  -> char)
    text

main :: IO ()
main = putStrLn (
    illuminate "Optimal Dark")

☀ptimal ◗ark
        
        

Terminal fixed width

Lode renders some characters, such as arrows ←↓↑→, using two-columns. While this renders well on the web and in many modern applications, some terminals expect all characters to be exactly one column. The Lode font family includes a "Lode Term" with single-column variants for all multi-column characters.

↑↑↓↓←→←→ Ⓑ Ⓐ Start
←↖↑↗→↘↓↙← — ⏹▲●

Texture healing

Monospace fonts face a forced tradeoff: characters of typically very different widths must each fill the same space. Narrow characters like i, j, and l use serifs and hooks to visually fill the space, however wide characters like w and m must be compressed, reducing their clarity. This is most apparent when pairs of narrow and wide characters are next to each other.

When possible Lode uses "texture healing" to replace these glyphs with contextual alternates (calt) with more natural widths while still aligning to the monospace grid, resulting in a more consistent visual density and improved clarity.

// Immutable programming for the www
let myNext = {...myPrev, width: minWidth }

// Min max window widths
window.onload = () => {
  const images = document.querySelectorAll('img');
  const minWidth = Math.min(...images.map(img => img.width))
  for (const image of images) {
    const aspectRatio = image.height / image.width
    image.width = minWidth
    image.height = minWidth * aspectRatio
  }
}

How does it work?

  1. First, adjacent pairs of "wide" and "narrow" letters (such as "mi") are replaced with alternates allowing the wide to expand towards the narrow which shrinks to make room. Triplets (such as "mim" or "imi") adjust from both sides.
  2. Then, any unexpanded wide letter can expand into narrow punctuation (like "m."). Doing this as an following step, as opposed to considering all punctuation "narrow", prioritizes expanding within a word rather than treating punctuation or whitespace as part of a triplet (for example "whim."). This also includes narrowed - and _ ("x-w" and "m_") and expanding within enclosing brackets ("(m)" and "[w]").
  3. Similarly, wide letters can then expand into whitespace ("m ").
  4. Finally, an expanded wide next to a non-expanded wide (like "immu") results in both glyphs becoming half-expanded and shifted.

The texture healing technique was adopted from Monaspace, which has an excellent visual explainer of how it works.

Operator and markup ligatures

Lode is a typeface for code, and many common programming operators and text markup conventions have ligatures to improve their legibility without obscuring the original characters

Operators, comparators, and punctuation

Most common operators

<html> </html> <> </> <!-- -->
== != === !== <= >= += -= *= **= /= <<= >>= >>>= &= ^= |= ||= &&= ??=
x++ y-- z**n a<<n b>>n a>>>b a&&b a||b
(x, ...y) => [a, ...b]
{| |} [| |] <> /\ \/ _|_ -| |-
<- -> <-| >=> <~~> /-> -->--><--<

Literals and escape sequences

3x4 0x0f31 0o755 0b0110011

Continuous lines

Three or more of some characters produce continuous lines for use as rules, underlines, or page boundaries.

_ ____________________________
- ----------------------------
+ ++++++++++++++++++++++++++++
^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# ############################

Many compilers and REPLs highlight errors with strings of ^ or ~. Lode replaces three or more as continuous squiggly underlines.

Immutable data-sturctures
          ^^^^^^^^^^^^^^^
          Did you mean "data-structures"?

for (const x of const y) {}
                ~~~~~
                Unexpected token 'const'

More

I'll find something to put here...

(defn lazy-loop [n]
(lazy-seq
  (when (pos? n)
    (cons "When life gives you lambdas, make lazy loops."
          (lazy-loop (dec n))))))