How to Use ToolJet: Build Your First Internal App (Drag-Drop UI, Queries, Docker Deploy)
CodexFuse Team · 2026-11-06T14:22:58.881Z · 25 min read min read
How to Use ToolJet: Build Your First Internal App (Drag-Drop UI, Queries, Docker Deploy)
Learning how to use ToolJet takes about an hour the first time, from the Docker install to a released internal app your team can open in a browser. ToolJet is an open-source low-code framework for building custom internal tools, and it ships with its own PostgreSQL-backed database, a visual app builder, and a query layer that connects to more than 100 data sources. This ToolJet tutorial follows the full arc in one guide: install it with Docker, create your first table in ToolJet DB, write your first query, drag a table onto the canvas, and release the app.
Every version, command, and limit here is pinned to the current LTS release, v3.20.255-lts, published 4 November 2026.
To use ToolJet, run the official try-it Docker command, open the app in your browser, create a table in ToolJet DB, add a query that lists the table's rows, drag a Table component onto the canvas and bind it to the query, then preview, promote the version to production, and release it. You need no frontend code, no separate backend, and no paid account, because the Community Edition is free and self-hosted under the AGPL-3.0 license. The whole first app fits in seven steps, and the Docker section below walks through them in order.
All facts in this guide are as of November 2026. CodexFuse offers no ToolJet tool, so this guide teaches the open-source project itself, step by step, with every version, command, and limit taken from the official docs, the official blog, the pricing page, and the GitHub repository.
What Is ToolJet, Exactly?
ToolJet is an open-source low-code platform for building internal tools such as admin panels, dashboards, and approval flows. The official definition is short: ToolJet is an open-source low-code framework to build and deploy custom internal tools. You describe the tool you need, connect your data, and refine the result on a visual canvas, instead of writing a frontend and a backend from scratch.
Every ToolJet app follows the same three-step model. First, you connect to data sources, either the built-in ToolJet DB or an existing database, API, or SaaS tool. Second, you build queries that fetch or change that data.
Third, you build the user interface by dragging components such as tables, charts, and forms onto the canvas. The query layer is the link between the interface and the data, and the components react to the query results automatically.
ToolJet connects to more than 100 data sources, including PostgreSQL, MongoDB, MySQL, Snowflake, BigQuery, REST and GraphQL APIs, Airtable, Stripe, Google Sheets, and cloud storage such as AWS S3. The builder ships with more than 80 components, and you can write JavaScript or Python queries when the visual query builder is not enough. The Community Edition is licensed under AGPL-3.0 and self-hosts on Docker or Kubernetes, while ToolJet Cloud offers a hosted path with a free tier.
The fastest way to run it yourself is Docker, and the Docker beginner guide on CodexFuse covers containers from the start if you have never used them.
The project is actively maintained and widely used. Its GitHub repository has 41,201 stars and 5,511 forks, or 7.48 stars per fork, and it was created on 30 March 2021, which makes it 2,047 days old on 6 November 2026. The repository was updated on the day this guide was written, and the LTS line received five patches in the nine days from 26 October to 4 November 2026.
That pace is why this guide pins every command to a named release instead of saying "the latest version" and leaving it at that.
What You Need Before You Start
You need very little to follow this guide, and everything on the list is free. Docker is the only real prerequisite for the self-hosted path, and a modern browser is the only other tool you will touch. If you would rather skip Docker entirely, you can sign up for a free ToolJet Cloud account instead and start at the table-creation step, because the app builder works the same way in both places.
| What you need | Why you need it | Notes |
|---|---|---|
| Docker Desktop or Docker Engine | Runs the ToolJet server and its built-in PostgreSQL in one container | Must be installed and running before the try-it command |
| A modern browser | The whole app builder runs in the browser | Chrome, Firefox, Edge, or Safari all work |
| A ToolJet account or a Docker install | You need a workspace to build in | Cloud signup is free; Docker needs no account at all |
| Basic SQL (helpful, not required) | Speeds up writing queries for external databases | ToolJet DB queries use a visual builder, so SQL is optional |
Pick one path and stick with it for your first app. The Docker path is the one this guide walks through, because it works offline, costs nothing, and keeps your data on your own machine. The Cloud path skips the install entirely, and the only difference is that ToolJet hosts the server for you.
Both paths lead to the same Database tab, the same Query Panel, and the same canvas.
How Do I Install ToolJet With Docker?
Installing ToolJet with Docker takes seven steps, and the first three get a working server on your machine. The ToolJet Docker install below runs a single container that already has PostgreSQL configured inside it, and all data lives in a Docker volume named tooljet_data. The command below is the current one from the official docs, and it uses the image tooljet/try:ee-lts-latest with the PostgreSQL 16 data path.
- Install Docker Desktop or Docker Engine and start it, then confirm it is running.
- Run the official try-it command below in your terminal.
- Open http://localhost in your browser and create your workspace admin account.
- Stop the server with docker stop tooljet whenever you finish, and start it again with docker start tooljet.
- For a real deployment, switch to the production Docker Compose setup below instead of the try-it container.
- Set the TOOLJET_HOST variable to your public address or domain before you share the app.
- Back up both PostgreSQL databases before every upgrade, then update the image tag and restart.
docker run \ --name tooljet \ --restart unless-stopped \ -p 80:80 \ --platform linux/amd64 \ -v tooljet_data:/var/lib/postgresql/16/main \ tooljet/try:ee-lts-latest
The server runs on port 80 by default, so you open it at http://localhost with no port number. If port 80 is already taken on your machine, the docs offer a variant on port 8080 that adds -p 8080:8080 -e PORT=8080 to the same command. Do not copy the older Docker Hub snippet that uses tooljet/try:latest with the PostgreSQL 13 path, because the current docs supersede it.
Stop and start the container with the two commands below, and your data survives in the tooljet_data volume.
docker stop tooljet docker start tooljet
The try-it container is for learning, not for production. A production install uses Docker Compose with the image tooljet/tooljet:ee-lts-latest or a pinned tag such as tooljet/tooljet:v3.20.255-lts, and it keeps the application database and the ToolJet DB data in separate PostgreSQL databases. The setup downloads the production compose file and an example environment file, then runs a script called internal.sh that generates the LOCKBOX_MASTER_KEY, the SECRET_KEY_BASE, and the PostgreSQL password for you.
curl -LO https://tooljet-deployments.s3.us-west-1.amazonaws.com/docker/docker-compose-db.yaml mv docker-compose-db.yaml docker-compose.yaml mkdir postgres_data curl -LO https://tooljet-deployments.s3.us-west-1.amazonaws.com/docker/.env.internal.example curl -LO https://tooljet-deployments.s3.us-west-1.amazonaws.com/docker/internal.sh chmod +x internal.sh mv .env.internal.example .env ./internal.sh docker-compose up -d
Set TOOLJET_HOST to your public IPv4 address or your custom domain, and it must start with http:// or https://. Upgrades follow a fixed order: back up both databases, run docker compose down, change the image tag to the newest LTS release, and run docker compose up -d. The LTS line releases a new version every three to five months with at least 18 months of support, and the current pin for this guide is v3.20.255-lts.
A beta release named v3.21.93-beta also exists, published 5 November 2026, but it is a beta and must never be treated as the current release.
docker compose down # change the image tag to tooljet/tooljet:v3.20.255-lts docker compose up -d
How Do I Create My First Table in ToolJet DB?
ToolJet DB is the built-in database that ships with ToolJet, and it is built on top of PostgreSQL. You do not need to install or connect anything to use it, which is why it is the right place for your first table. The example in this guide is an employee directory, the same shape the official quickstart uses, with one row per employee.
Open the Database tab in the left sidebar and click Create new table at the top-left. Name the table employees, and add one column per field: firstname, lastname, email, phone, department, position, joining, and status. The id field is present by default as the unique identifier for each row.
Click Create at the bottom-right, then click Add New Row and type a few real-looking rows so the table has data to show.
Table: employees Columns: id - primary key, auto-increment (present by default) firstname - string lastname - string email - string phone - string department - string position - string joining - date status - string
The same flow works for any first table, and the official blog uses a todo list with the same steps: a table named todoList, an id field that is the primary key and auto-increments, a task field that holds a string, and a status field that holds a boolean. Pick whichever example matches the app you actually want, because the query and UI steps are identical either way. The documented flow in this section comes from the current vendor blog tutorial and the archived quickstarts, so a few UI labels may have shifted in the 3.20 interface even though the steps are the same.
Know the free-tier ceiling before you fill the table. On the Free, Basic, and Pro plans, ToolJet DB allows 10 tables and 500 rows, while the Team and Enterprise plans allow unlimited tables and rows. Five hundred rows sounds small, but it lasts longer than you might expect: a team adding 10 rows a day takes 50 days to fill it, and a team adding 20 rows a day takes 25 days.
The computed block near the end of this guide shows that arithmetic, and it is worth running before you decide whether the free tier fits your app.
How to Use ToolJet Queries: Create Your First Query
A query is the link between your app's interface and your data, and it is how ToolJet talks to every data source. Queries are created in the Query Panel at the bottom of the App Builder, where you can use a visual form-based builder or write code and SQL by hand. Click the plus button in the Query Panel, pick a data source, and the query editor opens.
Create your first query by clicking the plus button, selecting ToolJet Database, and renaming the query getEmployees. Choose the employees table and the List Rows operation, enable the run-on-load setting, and click Run. The query returns every row in the table, and because it runs on load, the data is ready the moment the app opens.
Preview shows you what a query returns before you connect it to the interface, and Run executes it for real.
| Operation | What it does | When to use it |
|---|---|---|
| List Rows | Reads every row that matches your filters | Filling a table or a list when the app opens |
| Create Row | Inserts one new row into the table | Saving a form or an added row from the interface |
| Update Rows | Changes the rows that match your filters | Editing a record from the table or a form |
| Delete Rows | Removes the rows that match your filters | Deleting a record with a button click |
| Join Tables | Combines rows from two tables | Showing related data, such as employees with departments |
Queries are not limited to ToolJet DB. The same Query Panel connects to any REST API endpoint, and learning what an API is helps here, because a REST query is just a method, a URL, and parameters sent to another service. SQL sources such as PostgreSQL, MySQL, and SQL Server offer a GUI mode or a SQL mode where you write the query yourself.
JavaScript and Python queries cover business logic and data transformations that no visual builder can express.
Add a second query that writes data, and name it addEmployee. Choose the employees table and the Create Row operation, then map each column to a value from the interface, such as the email typed into a new table row. The values below come from the official quickstart, and they read the row the user just typed into the table component.
Wire this query to a button in the next section, and your app will read and write, not just read.
Query: addEmployee
Data source: ToolJet Database
Table: employees
Operation: Create Row
Values:
email = {{components.table1.newRows[0].email}}
firstname = {{components.table1.newRows[0].firstname}}
lastname = {{components.table1.newRows[0].lastname}}
department = {{components.table1.newRows[0].department}}
How Do I Build the UI With Drag-and-Drop Components?
Build the interface on the empty canvas that appears when you click Create new app on the Dashboard. The Component Library sits on the right side of the App Builder, and you drag components from it onto the canvas. Tables, charts, forms, buttons, and text components are all there, and each one has events such as on click, on row selected, and on page changed.
Drag a Table component onto the canvas, click it, and open its properties panel on the right. Under the Data property, enter the binding below, and the table fills with the rows returned by your getEmployees query. The table generates its columns automatically from the data, so you do not configure one column at a time.
Change the query, and the table changes with it, because the binding is live.
{{queries.getEmployees.data}}
The same binding pattern works for every component that shows data. A chart takes the same array of objects, a text component takes a single value such as {{queries.getEmployees.data.length}}, and a form takes one row. The current Table docs confirm the pattern with their own example, {{queries.restapi1.data}}, and they recommend the Button column for row actions, because the older Action Buttons are deprecated.
Keep the layout simple for your first app: one table on the left, one form or button row above it, and nothing else until it works.
ToolJet also offers a faster starting point than dragging every component by hand. ToolJet AI generates multi-page apps from a plain-language prompt, and the generated pages and queries stay editable in the visual builder. You can also build from Claude Code, Codex, or Cursor through the ToolJet MCP server, and the Claude Code beginner guide on CodexFuse covers that coding agent from the start if you want the agent-driven path.
Either way, the canvas is the source of truth, and generated work is only a starting point you refine visually.
How Do I Add a Button That Writes Rows?
Reading data is only half of an internal tool, and the other half is writing it back. The Table component has an Add new row button at the bottom-right, and clicking it opens a form for one new row. Wire that form to your addEmployee query with an event handler, and the button becomes a working save action.
Select the Table component and open its event handlers. Add a handler with the event Add new rows, the action Run Query, and the query addEmployee. When a user fills in the form and confirms, ToolJet runs addEmployee, and the new row appears in the table.
The getEmployees query runs again after the write, so the table refreshes without a page reload. This is the complete read-write loop: list the rows, add a row, and watch the table update.
Buttons work the same way anywhere else in the app. A standalone Button component takes an on click event, and its action can run a query, open a page, show a message, or run JavaScript. Give every query a clear name before you wire it, because the event handler lists queries by name, and a name such as addEmployee is far easier to find than query3.
Test the write path with one row before you share the app, and check the table in ToolJet DB to confirm the row actually landed.
How Do I Preview, Release, and Share My App?
Preview, release, and share sit at the top-right of the App Builder. Preview opens the app exactly as an end user will see it, with the draft version and the live queries. Fix anything that looks wrong in the draft, because the draft is the only version you can edit.
Saved versions are finalized checkpoints: they cannot be edited, and they exist so you can promote, release, and roll back safely.
Release the app in four steps. First, save the draft version you are happy with. Second, promote it from Development to Staging, review it there, and then promote it to Production.
Third, click the Release button beside the version name in Production and confirm, which releases the current version and replaces the previous one. Fourth, share the app with the Share button, which gives you a URL with a customizable slug. Only one version of an app can be released at a time, and rolling back is the same flow in reverse: pick an earlier production version and release it instead.
ToolJet keeps three environments by default: Development, where you build and test; Staging, where you review before production; and Production, where end users work. They cannot be removed or renamed, and new versions are only created in Development. Version control starts on the Pro plan, and Git sync is a Team plan feature, so the free tier releases apps without Git.
The GitHub beginner guide on CodexFuse covers Git from the start if the Git sync workflow is new to you. For a production install, the same ToolJet Docker image runs on Docker Compose or Kubernetes, and the Kubernetes beginner guide on CodexFuse covers that platform from the start.
ToolJet vs AppSmith: Which Open-Source Low-Code Platform Fits?
ToolJet and AppSmith are the two best-known open source low code platforms for internal tools, and both build admin panels, dashboards, and CRUD apps for free when self-hosted. The differences that matter are the license, the pricing model, and the builder style, not the feature checklist. ToolJet bills per builder and includes end users up to the plan limit, while AppSmith bills per user, so a team with many end users and few builders pays less on ToolJet.
| Feature | ToolJet | AppSmith |
|---|---|---|
| License | AGPL-3.0 (Community Edition) | Apache-2.0 (Community Edition) |
| Pricing model | Per builder; end users included to the plan limit | Per user; $15 per user per month on Business, up to 99 users |
| Builder style | Guided drag-and-drop builder with prompt-to-app generation | Visual builder that leans on JavaScript bindings |
| Logic language | JavaScript and Python | JavaScript-first |
| Workflows | Self-hosted only | Available on the hosted Business plan |
| Git | Git sync on the Team plan and up | Native Git-based version control |
Choose ToolJet if you want the more guided building experience, native prompt-to-app generation, or documented Python support. Choose AppSmith if you are comfortable with JavaScript bindings, need workflows in a hosted workspace, or prefer flat per-user Business pricing. An independent hands-on test of both tools found that ToolJet gave the simpler table setup and the only full prompt-to-app generator, while AppSmith was the only platform where the same tester completed a cloud approval workflow.
ToolJet's own comparison page lists its stars at 41,000-plus and AppSmith at 37,300-plus, which matches the 41,201 stars the GitHub API reported for ToolJet on 6 November 2026. One caution: AppSmith AI reached end of life on 30 September 2026, according to third-party reporting, so do not count it as a current AppSmith capability.
How Much Does ToolJet Cost?
ToolJet costs nothing to self-host with the Community Edition, and the Cloud free tier costs nothing either. The paid plans bill per builder, not per user, and the annual rates below come from the official pricing page. The Basic plan sits between Free and Pro with the same seat limits as Free and 2,000 AI credits per builder, but its dollar price did not come through clearly on the official page, so this guide states no figure for it.
Enterprise pricing is custom on the official page, and third-party reports of a 3,000-dollar monthly starting price are not official.
| Plan | Price | Builders | End users | Apps | AI credits |
|---|---|---|---|---|---|
| Cloud Free | $0 per builder per month | 2 | Up to 50 | Up to 10 | 100 per month |
| Cloud Basic | Not shown clearly on the official page | 2 | Up to 50 | Up to 10 | 2,000 per builder |
| Cloud Pro | $79 per builder per month, annual billing | Unlimited | Up to 50 | Up to 10 | 2,000 per builder |
| Cloud Team | $199 per builder per month, annual billing | Unlimited | Up to 100 | Unlimited | 3,000 per builder |
| Cloud Enterprise | Custom | Custom | Unlimited | Unlimited | Custom |
Pro adds version control, custom styling, and email support to the free features, and Team adds SSO, custom user groups, white labelling, a custom domain, audit logs, Git sync, and priority support. Self-hosted pricing mirrors Cloud: the self-hosted Free tier is $0 with the same limits, the self-hosted Team plan is $199 per builder per month, and the self-hosted Enterprise plan adds air-gapped deployment and multi-instance deployments. AI credit add-ons cost $1 per 100 credits on the pay-as-you-go rate.
The computed block below turns the monthly rates into yearly totals, so a team can compare them at a glance. Pro costs $948 per builder per year, and Team costs $2,388 per builder per year.
# Computed from the figures cited in this guide (run 2026-11-06)
repo_created = "2021-03-30"
days_old = 2047
stars, forks = 41201, 5511
print("repo age (days):", days_old)
print("stars per fork:", round(stars / forks, 2))
print("fork ratio (%):", round(forks / stars * 100, 1))
print("open issues as share of stars (%):", round(947 / stars * 100, 1))
print("days since v3.20.255-lts (2026-11-04):", 2)
print("days since v3.20.252-lts (2026-10-30):", 7)
print("days since v3.20.0-lts (2025-09-23):", 409)
print("LTS patches 250 -> 255 in (days):", 9)
print("Pro annual cost per builder ($):", 79 * 12)
print("Team annual cost per builder ($):", 199 * 12)
print("500 ToolJet DB rows at 10 new rows/day (days):", 500 // 10)
print("500 ToolJet DB rows at 20 new rows/day (days):", 500 // 20)
# Output:
# repo age (days): 2047
# stars per fork: 7.48
# fork ratio (%): 13.4
# open issues as share of stars (%): 2.3
# days since v3.20.255-lts (2026-11-04): 2
# days since v3.20.252-lts (2026-10-30): 7
# days since v3.20.0-lts (2025-09-23): 409
# LTS patches 250 -> 255 in (days): 9
# Pro annual cost per builder ($): 948
# Team annual cost per builder ($): 2388
# 500 ToolJet DB rows at 10 new rows/day (days): 50
# 500 ToolJet DB rows at 20 new rows/day (days): 25
What Are the Limits and Common Mistakes?
The most common mistake is installing the wrong release. Pin your install to v3.20.255-lts, the current LTS release, and treat the beta line as what it is: a preview, not the version you deploy. The second mistake is copying install commands from the 2022 tutorials that still rank for this topic, because they use the old Docker Compose flow with a database seed step and a seed login that no longer applies.
The current docs command in this guide is the one to use.
The free tier has real ceilings, and they are worth knowing before you build on them. ToolJet DB allows 10 tables and 500 rows on the Free, Basic, and Pro plans, and version control needs the Pro plan while Git sync needs the Team plan. Workflows run only on self-hosted installs, and multiple environments need the Team plan on self-hosted installs or the Enterprise plan on Cloud.
The try-it Docker container is a single container with PostgreSQL inside it, so it is a learning setup, and the production Compose install is the right base for anything your team depends on.
Security deserves one paragraph of its own. ToolJet had a signup-bypass vulnerability fixed in v3.20.242-lts, and pinning to v3.20.255-lts puts you past that fix. Keep the generated LOCKBOX_MASTER_KEY and SECRET_KEY_BASE private, because they protect the encrypted datasource credentials stored in the database.
Never test against apps or databases you do not own, and give each end user only the permissions their role needs, because the query-level permissions and app roles exist for exactly that reason.
What Can You Build Next With ToolJet?
Your employee directory is a template, not a finished product, and the same three steps build almost any internal tool. Turn the directory into an approval flow by adding a status column and a button that runs an Update Rows query. Turn it into a support dashboard by pointing a query at your helpdesk API instead of ToolJet DB.
Turn it into an inventory tracker by swapping employees for stock items and adding a low-stock filter.
The official blog shows how far the same pattern stretches. One tutorial builds a todo app on ToolJet DB, and another builds an AI code explainer that sends pasted code to Claude and shows the explanation beside it. Both use the same arc you just followed: a table, a query, a canvas, and a release.
Start with one small tool your team actually opens every day, release it, and let the requests for the next one tell you what to build after that.
One lane is worth naming so it never becomes a rival page. Windmill.dev, covered in a separate CodexFuse guide, is the code-first automation lane: you write scripts that run jobs on a schedule or a trigger. ToolJet is the low-code lane for internal apps with a visual interface, and the two solve different problems.
Pick ToolJet when people need to see and edit data, and pick Windmill when a job needs to run on its own.
Sources
ToolJet's official docs supplied the Docker install, the production Compose setup, the query system, the version control and release flow, and the current LTS table. The pages used were the try-it guide, the Docker deploy guide, the choose-your-ToolJet version table, the creating-and-managing-queries guide, the version-control guide, the release-and-rollback guide, the Table component docs, and the upgrade-to-v3 guide.
ToolJet's homepage and pricing page supplied the product definition, the 100-plus data source claim, the 80-plus component claim, the four-step build flow, and every price and plan limit in the pricing table. The official blog supplied the todo-application tutorial updated 23 October 2026, the AI code explainer tutorial, the ToolJet-versus-AppSmith comparison, and the reconciliation-workbench post that dates the version-control plan gating.
GitHub supplied the repository facts through its API: 41,201 stars, 5,511 forks, the AGPL-3.0 license, creation on 30 March 2021, and the release dates for v3.20.255-lts on 4 November 2026 and v3.21.93-beta on 5 November 2026. The archived ToolJet docs for versions 2.19.0 and 2.35.0 supplied the quickstart flows for the time-tracker and employee-directory examples, and the 2022 scien.cx tutorial and the toptool.app review showed how stale the competing field is.
Two independent comparisons supplied the ToolJet-versus-AppSmith detail: the emergent.sh hands-on test of both platforms and the exploreai.directory listing for AppSmith pricing and licensing. All figures in this guide come from the sources above, fetched on 6 November 2026, and no search-volume figure exists for the primary keyword, so none is stated.
Frequently Asked Questions
Is ToolJet really free?
Yes, the Community Edition is free and open source under the AGPL-3.0 license, and you can self-host it on Docker or Kubernetes without paying anything. ToolJet Cloud also has a free tier at $0 with 2 builders, up to 50 end users, up to 10 apps, and 100 AI credits a month. Paid plans start at $79 per builder per month on Pro, and they add version control, more AI credits, and support.
Do I need to know how to code to use ToolJet?
No, the visual builder and the GUI query mode cover the whole first app in this guide, and you can build tables, forms, and buttons without writing code. JavaScript and Python queries are optional extras for business logic and data transformations that the visual builder cannot express. Basic SQL helps with external databases, but ToolJet DB queries need none at all.
What is the difference between ToolJet DB and PostgreSQL?
ToolJet DB is ToolJet's built-in database, and it is built on top of PostgreSQL, so you get a real relational database without installing or connecting one. You create tables from the Database tab and query them with the visual builder, and the data lives in the same PostgreSQL that ToolJet itself uses. You can also connect an external PostgreSQL database as a separate data source whenever you need your data to live outside ToolJet.
Can I use ToolJet with my existing database?
Yes, ToolJet connects to more than 100 data sources, including PostgreSQL, MySQL, MongoDB, MS SQL Server, Snowflake, and BigQuery, plus REST and GraphQL APIs and tools such as Airtable, Stripe, and Google Sheets. Add the data source from the Query Panel or the Data Sources page, enter the connection details, and build queries against it exactly as this guide does for ToolJet DB. Your existing data stays where it is, and ToolJet only reads and writes through the connection you configure.
Is ToolJet better than AppSmith?
It depends on your team, because the two platforms price and build differently: ToolJet bills per builder with end users included to the plan limit, offers a guided builder with prompt-to-app generation and Python support, and keeps workflows self-hosted only, while AppSmith bills $15 per user per month on its Business plan, leans on JavaScript bindings, and offers workflows on its hosted plan. Both are free to self-host, so the honest test is to build the same small app in each and keep the one your team finishes faster.




