ADR-0006 — Container Runtime: native config.toml + Palette.to_config_toml()
Date: 2026-05-31 Status: Accepted
Context
Streamlit Container Runtime (Snowflake Workspace) supports .streamlit/config.toml
natively, unlike legacy SiS running on a warehouse.
This file unlocks two things the library could not do cleanly before:
-
primaryColorat the React level — Streamlit applies it directly in the React component, not via CSS. The KNOWN LIMITATIONS instyle.css(slider track fill, date picker selected day) existed because--primary-colorinjected via CSS is ignored by React. Withconfig.toml, these limitations disappear. -
Fonts without base64 —
fontFilesinconfig.tomlallows referencing TTF/WOFF2 files bundled in the project. The base64 hack (ADR-0005) is no longer needed in Container Runtime.
Decision
Add Palette.to_config_toml(font_files=None) to core/constants.py.
This method generates the content of .streamlit/config.toml from a Palette:
- [theme.light] + primaryColor
- [theme.dark] + primaryColor (dark auto-computed if Palette.dark is None)
- [theme] + font = "custom" + fontFiles (if font_files provided)
setup_page() is not modified. The font=None parameter already existed — it just
needs to be passed explicitly in Container Runtime.
Usage
from pinky_streamlit import PALETTES
# 1. Generate config.toml once (paste into .streamlit/config.toml)
print(PALETTES.PYTHIA.to_config_toml(font_files=["static/DMSans.woff2"]))
# 2. In each page
setup_page(session, palette=PALETTES.PYTHIA, font=None)
# ↑
# config.toml handles font + primaryColor
# setup_page() only injects style.css + CSS variables
Responsibility split
What config.toml handles |
What setup_page() still handles |
|---|---|
primaryColor (native React) |
CSS variables (--primary-darker, color-mix() shades…) |
Font via fontFiles |
Component overrides (checkbox, toggle, pills, tabs…) |
| Native light / dark switch | style.css normalization |
CSS variables and component overrides cannot be declared in config.toml —
setup_page() remains necessary even in Container Runtime.
Consequences
Positive:
- KNOWN LIMITATIONS in style.css (slider, date picker) resolved natively
- End of the base64 hack for new Container Runtime apps
- AppFont and _load_font_css() remain for backward compat (legacy SiS, local dev)
- 8 new tests in test_constants.py cover all cases
Negative:
- The app must generate config.toml once and commit it — a manual step
- config.toml and Palette can diverge if one is updated without the other
→ mitigation: to_config_toml() is the source of truth, always regenerate from the palette
Relation to ADR-0005
ADR-0005 (base64 bundled font) remains valid for:
- Legacy SiS on warehouse (no config.toml support)
- Local dev without config.toml
In Container Runtime, fontFiles in config.toml is the preferred method.
Both modes coexist via font=DEFAULT_FONT (legacy) vs font=None (container).