Skip to main content

Ultra-fast Python syntax highlighter for FastHTML/StarHTML with Datastar support

Project description

Starlighter

Python Version PyPI Version License Zero Dependencies

Server-side Python syntax highlighter with zero dependencies. Built for StarHTML with Datastar-aware tokenization, and compatible with FastHTML.

Features

  • Fast: ~1.5ms P99 for 200-line files, ~3ms for 500-line files
  • XSS-safe: All output is entity-encoded
  • Zero dependencies: Pure Python standard library
  • 17 built-in themes: GitHub, VS Code, Monokai, Catppuccin, Dracula, Nord, Solarized, One Dark, Xcode (dark + light variants)
  • StarHTML-aware: Distinct token classes for HTML elements, Datastar attributes, signals, and CSS class/style strings
  • FastHTML compatible: Works with both StarHTML and FastHTML projects

Installation

# Using uv (recommended)
uv add starlighter

# Using pip
pip install starlighter

Usage

Basic highlighting

from starlighter import highlight

code = '''def fibonacci(n):
    if n <= 1:
        return n
    return fibonacci(n-1) + fibonacci(n-2)

print(fibonacci(10))'''

html = highlight(code)

StarHTML-aware highlighting

The lexer recognizes StarHTML elements, Datastar attributes, and signal references, giving each a distinct token class:

from starlighter import highlight

code = '''Button(
    "Increment",
    data_on_click=count.add(1),
    cls="px-4 py-2 bg-blue-500"
)'''

html = highlight(code)
# Button  -> token-starhtml-element
# data_on_click -> token-datastar-attr
# cls string    -> token-css-class

You can also register custom elements, attributes, and signal names:

html = highlight(
    code,
    elements={"MyWidget", "AppShell"},
    attrs={"custom_bind"},
    signals={"count", "message"},
)

With StarHTML

from starhtml import *
from starlighter import CodeBlock, StarlighterStyles

app, rt = star_app(
    hdrs=(
        StarlighterStyles("github-dark", "monokai", "dracula"),
    )
)

@rt("/")
def home():
    sample = '''def greet(name: str) -> str:
    return f"Hello, {name}!"'''

    return Div(
        H1("Code Preview"),
        CodeBlock(sample, theme="github-dark"),
        cls="container"
    )

serve()

With FastHTML

from fasthtml.common import *
from starlighter import CodeBlock, StarlighterStyles

app, rt = fast_app(
    pico=False,
    hdrs=(StarlighterStyles("vscode"),)
)

@rt("/")
def get():
    return Div(
        CodeBlock('print("hello")', theme="vscode"),
        cls="container"
    )

serve()

Themes

17 themes are available:

Dark Light
github-dark (default) github-light
vscode-dark / vscode vscode-light
monokai catppuccin-latte
catppuccin-mocha nord-light
dracula solarized-light
one-dark xcode-light
nord-dark
solarized-dark
xcode-dark
from starlighter import get_theme_css

# Get raw CSS for a theme
css = get_theme_css("monokai")

# Use StarlighterStyles to load multiple themes at once
StarlighterStyles("github-dark", "monokai", "dracula")

# Auto-switch between themes based on prefers-color-scheme
StarlighterStyles("github-dark", "github-light", auto_switch=True)

CSS Token Classes

Class Tokens
.token-keyword def, class, if, for, return, ...
.token-string "text", 'text', f"..."
.token-comment # ..., docstrings
.token-number 42, 3.14, 0xFF
.token-operator +, -, ==, !=
.token-identifier Variable and function names
.token-builtin print, len, str, range, ...
.token-decorator @app.route, @property
.token-punctuation (), [], {}, ,, :
.token-starhtml-element Div, Button, Input, ...
.token-datastar-attr data_on_click, data_bind, ...
.token-signal Signal variable references
.token-css-class Strings passed to cls=, data_class=
.token-css-style Strings passed to style=, data_style=

API

from starlighter import highlight, CodeBlock, StarlighterStyles, get_theme_css

highlight(
    code: str,
    language: str | None = "python",
    elements: set[str] | None = None,
    attrs: set[str] | None = None,
    signals: set[str] | None = None,
) -> str

CodeBlock(code: str, theme: str = "github-dark", **kwargs) -> Component

StarlighterStyles(*themes: str, auto_switch: bool = False, **kwargs) -> Style

get_theme_css(theme: str = "github-dark") -> str

Security

All input is HTML-entity-encoded before output. Script injection via code input is not possible:

code = 'return "</pre><script>alert(1)</script><pre>"'
html = highlight(code)
# Scripts are escaped: &lt;script&gt;alert(1)&lt;/script&gt;

Development

git clone https://github.com/banditburai/starlighter.git
cd starlighter
uv sync --all-extras
uv run pytest tests/ -v --cov=starlighter
uv run ruff check && uv run ruff format --check

Links

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

starlighter-0.2.0.tar.gz (10.9 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

starlighter-0.2.0-py3-none-any.whl (11.9 kB view details)

Uploaded Python 3

File details

Details for the file starlighter-0.2.0.tar.gz.

File metadata

  • Download URL: starlighter-0.2.0.tar.gz
  • Upload date:
  • Size: 10.9 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.7

File hashes

Hashes for starlighter-0.2.0.tar.gz
Algorithm Hash digest
SHA256 e74134ce1e38ef27b181c09e138021e327024d8fbe8d1054048962323540e04f
MD5 0a1efb51b99ae4266895ada4620ce152
BLAKE2b-256 ecb66b93e2a82094f5b483dfa6140dc5feb61d0e4630a41f0d85295d7bfcb653

See more details on using hashes here.

Provenance

The following attestation bundles were made for starlighter-0.2.0.tar.gz:

Publisher: release.yml on banditburai/starlighter

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file starlighter-0.2.0-py3-none-any.whl.

File metadata

  • Download URL: starlighter-0.2.0-py3-none-any.whl
  • Upload date:
  • Size: 11.9 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.7

File hashes

Hashes for starlighter-0.2.0-py3-none-any.whl
Algorithm Hash digest
SHA256 faab3babc81eb6b33bac4e86ded536e5381b87554497cafebe142b4b98264ce3
MD5 5e0f5772f86d2633c420ce1a3837a31b
BLAKE2b-256 697cecc8a9bce5737c4668f6e4963a114e610bb5b413a452133e7ce0032ff437

See more details on using hashes here.

Provenance

The following attestation bundles were made for starlighter-0.2.0-py3-none-any.whl:

Publisher: release.yml on banditburai/starlighter

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page