Skip to content

Latest commit

 

History

History
109 lines (87 loc) · 8.94 KB

AGENTS.md

File metadata and controls

109 lines (87 loc) · 8.94 KB

Streamlit Repo Overview

Streamlit is an open-source (Apache 2.0) Python library for creating interactive web applications and dashboards with focus on data apps and internal tools.

Tech Stack

  • Backend (Server): Python, Starlette/Uvicorn server, pytest
  • Frontend (Web UI): TypeScript, React, Emotion (CSS-in-JS), Vite, Vitest
  • Communication: Protocol Buffers (protobuf) over WebSocket.

Folder Structure

  • lib/: All backend code and assets.
    • streamlit/: The main Streamlit library package.
    • streamlit/elements/: Backend code of elements and widgets.
    • streamlit/runtime/: App runtime and execution logic.
    • streamlit/web/: Web server and CLI implementation
    • tests: Python unit tests (pytest).
  • frontend/: All frontend code and assets.
    • app/: Streamlit application UI.
    • lib/: Shared TypeScript library that contains elements, widgets, and layouts.
    • connection/: WebSocket connection handling logic.
    • utils/: Shared utilities.
    • component-lib/: Library for building Streamlit custom components v1.
    • component-v2-lib/: Library for building Streamlit custom components v2.
  • proto/streamlit/proto/: Protobuf definitions for client-server communication.
  • e2e_playwright/: E2E tests using playwright (via pytest).
  • scripts/: Utility scripts for development and CI/CD.
  • specs/: Product and tech specs for Streamlit features.
  • .github/workflows/: GitHub Actions workflows used for CI/CD.
  • wiki/: Documentation relevant for development of Streamlit.

Shell & Build Policy

  • Prefer make targets for all dev tasks (tests, lint, format, builds).
  • Always use uv run to run any Python command (e.g. uv run streamlit, uv run pytest, uv run ruff, uv run mypy, etc.).
  • Always use uv run for git commands that trigger hooks (e.g. uv run git commit, uv run git push). Pre-commit hooks require the uv environment to run linters and formatters.
  • The committed root uv.lock is the source of truth for normal development and CI. Do not hand-edit it.
  • For Python dependency changes, edit the relevant pyproject.toml, run uv lock, and commit both files. Also run uv lock after changing the package name or version. Use uv lock --upgrade-package <package> for a targeted upgrade, uv lock --upgrade for a full compatible upgrade, and uv lock --check to verify consistency.
  • The dev/CI [dependency-groups] in the root pyproject.toml use bare package names because uv.lock owns the versions: do not add lower-bound floors, reserve exact == pins for tools we deliberately hold back, and add upper caps (<) only for versions known to break us (mirrored by ignore entries in .github/dependabot.yml); a != exclusion of a single known-broken release needs no ignore entry. This does NOT apply to lib/pyproject.toml, whose version ranges are the published package's contract with users. See the comment above [dependency-groups] in the root pyproject.toml for details.
  • If uv.lock conflicts during a merge, restore it with git checkout origin/develop -- uv.lock, then run uv lock; never hand-merge it.
  • For Python unit tests: uv run pytest commands are allowed and encouraged for running specific tests during development.
  • For E2E tests: uv run pytest commands targeting e2e_playwright/ files are blocked by policy. Use make run-e2e-test <filename> instead.

make commands

Selection of make commands for development (run in the repo root):

  • help: Show all available make commands. [~1s]
  • check: Run all checks (format, lint, types, unit tests) on changed files only. Add E2E_CHECK=true to include E2E tests. [varies by changes]
  • protobuf: Recompile Protobufs for Python and the frontend. [~5s]
  • autofix: Autofix linting and formatting errors. [~30s]

Backend Development (Python):

  • python-init: Install the locked Python environment selected by PYTHON_DEPENDENCY_GROUP (dev by default).
  • python-lint: Lint and check formatting of Python files (ruff). [~1s]
  • python-tests: Run all Python unit tests (pytest). [~3min]
  • python-types: Run the Python type checker (mypy & ty). [~30s]
  • python-format: Format Python files (ruff). [~1s]

Frontend Development (TypeScript):

  • frontend-fast: Build the frontend (vite). [~40s]
  • frontend-dev: Start the frontend development server (hot-reload). [until stopped]
  • frontend-lint: Lint and check formatting of all frontend files (oxlint + eslint). [~45s]
  • frontend-knip: Run Knip unused-export and unused-dependency analysis. [~5s]
  • frontend-types: Run the TypeScript type checker on all files (tsc). [~15s]
  • frontend-format: Format all frontend files (oxfmt). [~2s]
  • frontend-tests: Run all frontend unit tests (vitest). [~5min]

E2E Testing (Playwright):

  • run-e2e-test: Run e2e test, via: make run-e2e-test st_command_test.py. [varies by test]

Debugging backend & frontend:

  • debug: Start Streamlit backend and Vite dev server together, via: make debug my_app.py. [until stopped]
    • Frontend hot-reload: Changes to frontend code (frontend/) are applied within seconds.
    • Backend hot-reload: Only changes to the app script trigger a rerun. Changes to the Streamlit library itself (lib/streamlit/) require restarting make debug.
    • Logs are written to a per-session directory under work-tmp/debug/ (e.g. work-tmp/debug/<session>/backend.log and work-tmp/debug/<session>/frontend.log).
    • work-tmp/debug/latest/ is a symlink to the most recent debug session (e.g. work-tmp/debug/latest/backend.log). If multiple sessions are running simultaneously, this symlink can move—prefer using the session directory printed by make debug.
    • Log files are cleared at the start of each session and persist after exit for post-mortem analysis.
    • Browser console.log() output appears in the session’s frontend.log.
    • See .claude/skills/debugging-streamlit/SKILL.md for the full debugging guide.

Development Tips

  • Follow existing patterns: Check neighboring files for conventions.
  • Comments must describe current behavior or why the code exists. Do not describe a previous state of the code or rely on change history.
  • Subagent model: When launching subagents, use the same model as the parent session (model: inherit / omit any model override). Do not switch to a different or faster model unless the user explicitly requests it. Prefer the named custom agents in .claude/agents/ when available.
  • You can use the work-tmp directory to store temporary files, specs, and scripts.
  • Use agent-wiki/ (gitignored, cloned on first use) to share intermediate files (specs, plans, learnings) relevant for the current PR. This is a local checkout of streamlit.wiki. Files are stored in pull-requests/<pr-number>/ and accessible at https://issues.streamlit.app/agent_wiki_explorer?file=<relative-path>. See sharing-pr-agent-artifacts skill.
  • If you fail to run a make command, remember to run it from the root / top-level directory.
  • Use make debug <script.py> to start both backend and frontend with hot-reload for debugging. The app URL will be printed on startup (default http://localhost:3001; 3000 is reserved for manual make frontend-dev; it may use 3002+ if you have other sessions running). Avoid pinning VITE_PORT unless you have a specific hard requirement (last resort).
  • Run make check after completing changes to run formatting, linting, type checking, and unit tests on all uncommitted files.
  • The main branch of this repository is develop.
  • For adding new elements, widgets, or features that span backend, frontend, and protobufs, see wiki/new-feature-guide.md.

Testing Strategy

  • Most new user-facing features should be covered by both unit tests and E2E tests.
  • Python Unit Tests: Test internal behavior without frontend. Located at lib/tests/streamlit/<package>/<module>_test.py mirroring lib/streamlit/<package>/<module>.py (legacy tests may vary).
  • Frontend Unit Tests: Test React components, hooks, and related functionality with Vitest and React Testing Library. Co-located as <Component>.test.tsx next to <Component>.tsx.
  • E2E Tests: Test the entire app logic end-to-end with Playwright. Located at e2e_playwright/<name>_test.py with app code in e2e_playwright/<name>.py. User-facing features should be covered by E2E tests (e.g., parameters and commands in the public st. API).
  • (Python) Type Tests: Verify public API typing with assert_type under both mypy and ty. Located at lib/tests/streamlit/typing/<command>_types.py. Update these for new st.* commands and for new or changed parameters.
  • AppTest: When a command can be represented as an element or block, support new st.* commands and new or changed parameters in AppTest (lib/streamlit/testing/v1/). See lib/streamlit/AGENTS.md.
  • Prefer running specific tests / test scripts for newly added tests instead the entire test suite.