The Problem
Enterprises building internal dashboards, workflow tools, or AI‑augmented UIs often cobble together disparate front‑ends, back‑ends, and custom connectors. The result is a maintenance nightmare: mismatched UI libraries, ad‑hoc API layers, and fragile secret handling. Teams need a single, extensible platform that supplies a visual builder, a consistent runtime for JavaScript/Python, and a clean path for adding plugins or AI‑generated components.
What This Does
The repository is a portfolio of seven self‑contained projects that together form the open‑source core of ToolJet CE:
| Project | Primary Scope | Key Files |
|---|---|---|
frontend | React‑based visual builder, component library, Storybook | frontend/src/AppBuilder/CodeEditor/autocompleteUtils.js, frontend/src/_hoc/withProfiler.jsx |
server | Flask‑/Express‑style API gateway, query execution, auth | (code files not listed individually) |
cypress-tests | End‑to‑end test suite for UI and marketplace | cypress-tests/cypress/plugins/index.js |
plugins | Sample connectors and custom widget scaffolding | plugins/... |
marketplace | Distribution channel for third‑party plugins | marketplace/... |
cli | ToolJet command‑line utilities for plugin generation | cli/package.json |
queryPanel | Small helper UI for query editing | queryPanel/... |
The frontend provides over 60 drag‑and‑drop widgets (e.g., FileButton.jsx, RadioButton.jsx) and a code editor that uses autocompleteUtils.js for intelligent suggestions. The server exposes REST endpoints that the UI consumes, while the plugins directory shows how new data‑source connectors can be added via the CLI. All parts are containerised (docker/ and deploy/docker/*.yaml) and can be orchestrated with Docker‑Compose or Kubernetes.
How It Is Wired
Execution begins at the frontend entry point defined by the Storybook config frontend/.storybook/main.js, which loads the React app and registers components. The UI imports frontend/src/_hoc/withProfiler.jsx; its withProfiler wrapper invokes onRenderCallback on every render, funneling performance data to frontend/src/modules/common/helpers/posthog.js where initPosthog and captureEvent forward metrics to the analytics backend.
When a user adds a widget, the UI calls autocompleteUtils.getLastSubstring → autocompleteUtils.getLastDepth to provide context‑aware suggestions. Those suggestions may trigger server‑side code via the API gateway in server/. The gateway reads environment variables from .env.example (runtime values are injected by Docker) and authenticates requests using the JWT secret defined in deploy/ec2/ee/.env (currently committed, see health section).
Plugin loading is handled by frontend/__mocks__/svg.js, which defines process and getCacheKey; these functions are the only two that the test harness (cypress-tests/cypress/plugins/index.js) directly calls, establishing the minimal surface area for SVG asset handling. The most widely referenced utility is posthog.js, which sits at the intersection of UI events and analytics, giving it the broadest blast radius.
The repository does not expose a single monolithic call graph; each sub‑project has its own startup script (e.g., docker-compose.yaml brings up the frontend, server, and database containers). No unified “main” file is present, reflecting the intentional modularity.
How To Use It
# Clone the repo
git clone https://github.com/moses-y/ToolJet.git
cd ToolJet
# Build and start all services (Docker Compose)
docker compose -f deploy/docker/docker-compose.yaml up -d
# Frontend runs on http://localhost:3000, server on http://localhost:8080
Required secrets are read from deploy/ec2/ee/.env; replace the file with a safe .env.example before production. The CLI can scaffold a new plugin:
cd cli
npm install
npx @tooljet/cli create-plugin my-connector
Real‑World Use
A SaaS ops team can host ToolJet CE behind an internal reverse proxy, connect it to their PostgreSQL warehouse, and let analysts build dashboards without writing code. When a new CRM API appears, a developer adds a connector in plugins/ using the CLI, pushes the Docker image, and the UI instantly lists the new data source.
Code Health & Issues
Static analysis produced 11 findings:
- Critical – Rotate credentials in
deploy/ec2/ee/.env; remove the file from Git and replace with an example. - High – Pin GitHub Actions to commit SHAs; remove
@vNtags in.github/workflows/*. - High – Delete the committed
.env(same as critical) and add a.env.example. - High – CI workflows never run tests; add a test step to each workflow.
- Medium – Declare least‑privilege
GITHUB_TOKENpermissions incloud-frontend-cf-pages-prod.yml. - Medium – Use
npm ci(or equivalent) in CI to respect lockfiles. - Medium – Add a dependency‑vulnerability scan (e.g.,
dependency-review-action). - Medium – Install a pre‑commit secret‑leak gate.
- Medium – Move large binaries (e.g.,
frontend/assets/libs/pyodide-0.23.2/*.whl) to Git LFS or external storage. - Medium – Set
persist-credentials: falseon the checkout step indeploy-to-stage.yml.
Additional hygiene notes: tests exist (1146 files) and are wired via Cypress, but the CI never executes them. A license file is present (AGPL). Secrets are currently tracked, which is a significant risk.
The Bottom Line
ToolJet provides a fully‑featured, modular platform for internal tool building, with a clear separation between UI, API, and extensible plugins. The codebase is extensive but suffers from serious secret‑management and CI hygiene issues that must be remedied before production deployment. It is suitable for teams comfortable managing Docker/Kubernetes environments and willing to tighten the security pipeline.