Skip to main content

Developer Guides

Flagsmith API

Local development

The project assumes the following tools installed:

  • Python. Any version allowed by requires-python in pyproject.toml is supported.
  • GNU Make.
  • Docker or a compatible tool like Podman. We recommend OrbStack for macOS.

To install dev dependencies, run make install.

To run linters, run make lint.

To run tests, run make docker-up test.

To prepare a dev database, run make docker-up django-migrate.

To bring up a dev server, run make serve, or make serve-with-task-processor to run the Task processor alongside the server.

Code guidelines: testing

The required diff test coverage for our backend PRs is 100%. This policy gives us more confidence to ship, helps us to find bugs earlier, and promotes the test-driven development (TDD) approach. We encourage you to add new tests, and modify existing ones, ahead of writing the code.

This codebase includes two kinds of tests:

  • Black box API tests in tests/integration directory. Ideally, these are intended to only invoke API endpoints, and verify their output.
  • Tests for individual modules, classes and functions in tests/unit directory.

We avoid class-based tests. To manage test lifecycle and dependencies, we rely on Pytest features such as fixtures, markers, parametrisation, and hooks. Read conftest.py for commonly used fixtures.

We recommend naming test functions using the test_{subject}__{condition}__{expected outcome} template, e.g. test_get_version__valid_file_contents__returns_version_number.

We use the Given When Then structure in all our tests.

Code guidelines: migrations

To auto-generate migrations for your new code, run make docker-up django-make-migrations.

The prompt will ask you for a name and not generate one; we avoid auto-generated migration names.

Squash newly added migrations whenever you can.

Code guidelines: typing

This codebase, including tests, is fully type-checked by Mypy in strict mode. Resolving existing # type: ignore comments is always welcome. If you happen to bring a new # type: ignore comment, please document the reason, and consider fixing a small number of adjacent # type: ignore comments, if possible and appropriate for the scope of your task.

To run a full type check, run make typecheck.

Code guidelines: design and architecture

Core API consists of Django apps with usual Django submodules like:

  • apps.py
  • middleware.py
  • models.py
  • serializers.py
  • views.py
  • urls.py

We tend to add our own layers in the following modules:

  • constants.py for app-wide constant variables.
  • dataclasses.py for dataclass definitions, typically used for internal data transfer objects (DTOs).
  • mappers.py for data mapping logic unrelated to API requests and responses.
  • services.py for encapsulated business logic. Our goal with this layer is to make the views, models and serialisers leaner, so that the business logic is more clearly defined and easier to compose.
  • tasks.py for defining asynchronous and recurring tasks.
  • types.py for custom type definitions, including typed dicts.

Code guidelines: Flagsmith on Flagsmith

To gate and gradually rollout features in the backend, we use the Flagsmith SDK in local evaluation mode:

from integrations.flagsmith.client import get_client

flagsmith_client = get_client("local", local_eval=True)
flags = flagsmith_client.get_identity_flags(
organisation.flagsmith_identifier,
traits=organisation.flagsmith_on_flagsmith_api_traits,
)
ai_enabled = flags.is_feature_enabled("ai")

To modify or add flags, edit integrations/flagsmith/data/environment.json, or run poetry run python manage.py updateflagsmithenvironment.

Flagsmith Frontend

Docker-based development

To bring up the API and database via Docker Compose:

curl -o docker-compose.yml https://raw.githubusercontent.com/Flagsmith/flagsmith/main/docker-compose.yml
docker-compose -f docker-compose.yml up

The application will bootstrap an admin user, organisation, and project for you. You'll find a link to set your password in your Compose logs:

Superuser "admin@example.com" created successfully.
Please go to the following page and choose a password: http://localhost:8000/password-reset/confirm/.../...

Local development

The project assumes the following tools installed:

To install dependencies, run npm install.

The API must be running on localhost:8000 (either via Docker or make serve in ../api).

To bring up a dev server, run ENV=local npm run dev.

To run linters, run npm run lint (or npm run lint:fix to auto-fix).

To run type checking, run npm run typecheck.

Environment configuration

Environment configuration is defined in project_*.js files (common/project.js for defaults, env/project_*.js for staging/prod/selfhosted), selected at build time based on the target environment. All configs support runtime overrides via globalThis.projectOverrides, allowing deployment-time customisation without rebuilding.

The bin/env.js script copies the appropriate env/project_${ENV}.js to common/project.js:

  • npm run dev → copies project_dev.js (staging API)
  • ENV=local npm run dev → copies project_local.js (localhost)
  • ENV=prod npm run bundle → copies project_prod.js (production)

For a full list of frontend environment variables, see the Flagsmith documentation.

Code guidelines

Testing

This codebase uses TestCafe for end-to-end testing. Tests are located in the e2e/ directory.

To run E2E tests (requires the API running on localhost:8000), run npm run test.

Typing

This codebase uses TypeScript. Run npm run typecheck to check for type errors.

We encourage adding types to new code and improving types in existing code when working nearby.

Design and architecture

The frontend is organised into:

  • common/ - Shared code (Redux store, RTK Query services, types, utilities)
  • web/components/ - React components
  • web/components/pages/ - Page-level components

State management uses Redux Toolkit with RTK Query for API calls. Services are defined in common/services/.

API types are centralised in:

  • common/types/requests.ts - Request types
  • common/types/responses.ts - Response types

For AI-assisted development, see CLAUDE.md.

Documentation

docs.flagsmith.com is built using Docusaurus 2, a modern static website generator.

Installation

npm install

Local Development

npm run start

This command starts a local development server and opens up a browser window. Most changes are reflected live without having to restart the server.

When forwarding port 3000 from a remote server or VM, you can run the dev server on 0.0.0.0 to make it listen on the local IP.

npm run start -- --host 0.0.0.0

Checking your changes with prettier

After you make changes to the documentation, you can check the changes by running the following command:

npx prettier --check docs

If you want to apply any fixes discovered, you can run the following command:

npx prettier <YOUR_DOC> --write

OpenAPI generator

We are using the https://github.com/PaloAltoNetworks/docusaurus-openapi-docs plugin to generate the OpenAPI docs. If static/api-static/edge-api.yaml changes you will need to rebuild the static files with:

npm run docusaurus clean-api-docs all
npm run docusaurus gen-api-docs all

and then commit them.

Build

npm run build

This command generates static content into the build directory and can be served using any static contents hosting service.

Deployment

This site is set to auto deploy to Vercel.