2.7 KiB
Penpot Common – Agent Instructions
A shared module with code written in Clojure, ClojureScript, and JavaScript. Contains multiplatform code that can be used and executed from the frontend, backend, or exporter modules. It uses Clojure reader conditionals to specify platform-specific implementations.
General Guidelines
To ensure consistency across the Penpot stack, all contributions must adhere to these criteria:
1. Testing & Validation
If code is added or modified in src/, corresponding tests in
test/common_tests/ must be added or updated.
- Environment: Tests should run in both JS (Node.js) and JVM environments.
- Location: Place tests in the
test/common_tests/directory, following the namespace structure of the source code (e.g.,app.common.colors->common-tests.colors-test). - Execution: Tests should be executed on both JS (Node.js) and JVM environments:
- Isolated:
- JS: To run a focused ClojureScript unit test: edit the
test/common_tests/runner.cljsto narrow the test suite, thenpnpm run test:js. - JVM:
pnpm run test:jvm --focus common-tests.my-ns-test
- JS: To run a focused ClojureScript unit test: edit the
- Regression:
- JS: Run
pnpm run test:jswithout modifications on the runner (preferred) - JVM: Run
pnpm run test:jvm
- JS: Run
- Isolated:
2. Code Quality & Formatting
- Linting: All code changes must pass linter checks:
- Run
pnpm run lint:cljfor CLJ/CLJS/CLJC
- Run
- Formatting: All code changes must pass the formatting check
- Run
pnpm run check-fmt:cljfor CLJ/CLJS/CLJC - Run
pnpm run check-fmt:jsfor JS - Use
pnpm run fmtto fix all formatting issues (pnpm run fmt:cljorpnpm run fmt:jsfor isolated formatting fix).
- Run
Code Conventions
Namespace Overview
The source is located under src directory and this is a general overview of
namespaces structure:
app.common.types.*– Shared data types for shapes, files, pages using Malli schemasapp.common.schema– Malli abstraction layer, exposes the most used functions from malliapp.common.geom.*– Geometry and shape transformation helpersapp.common.data– Generic helpers used across the entire applicationapp.common.math– Generic math helpers used across the entire applicationapp.common.json– Generic JSON encoding/decoding helpersapp.common.data.macros– Performance macros used everywhere
Reader Conditionals
We use reader conditionals to differentiate implementations depending on the target platform where the code runs:
#?(:clj (import java.util.UUID)
:cljs (:require [cljs.core :as core]))
Both frontend and backend depend on common as a local library (penpot/common {:local/root "../common"}).