# Appsmith User Guide

Appsmith is an open-source, low-code platform for building internal tools — dashboards, admin panels, customer-support consoles, CRUD apps, approval workflows, and IT-automation utilities. You connect a data source (a database, REST/GraphQL API, Google Sheet, or SaaS service), drag pre-built widgets onto a canvas, bind them to your data with a familiar `{{ }}` JavaScript syntax, and publish a working web app — without standing up a frontend project of your own.

This guide is for **app builders** (makers) and the people who **self-host Appsmith for a team**. It covers getting Appsmith running, building and publishing applications, connecting data, writing queries and JavaScript, version-controlling apps with Git, and troubleshooting. Deep configuration, deployment topologies, security hardening, and platform internals live in the companion **Appsmith Admin Guide**.

> [!NOTE]
> Appsmith ships in two editions from the same codebase: **Community Edition (CE)** — the Apache-2.0 open-source build (`appsmith/appsmith-ce`) — and **Enterprise Edition (EE)** (`appsmith/appsmith-ee`), which adds SAML/enterprise SSO, granular access control, audit logs, and other business features behind a license key. This guide focuses on capabilities present in CE and notes EE-only features where relevant.

---

## Table of Contents

1. [Quick Start](#1-quick-start)
2. [Installation](#2-installation)
3. [First-Run Setup](#3-first-run-setup)
4. [Core Concepts](#4-core-concepts)
5. [The App Editor Tour](#5-the-app-editor-tour)
6. [Connecting Data Sources](#6-connecting-data-sources)
7. [Writing Queries](#7-writing-queries)
8. [Building the UI with Widgets](#8-building-the-ui-with-widgets)
9. [Binding Data: The `{{ }}` Language](#9-binding-data-the---language)
10. [JavaScript Objects and Custom Logic](#10-javascript-objects-and-custom-logic)
11. [Common Tasks (Recipes)](#11-common-tasks-recipes)
12. [Publishing and Sharing Apps](#12-publishing-and-sharing-apps)
13. [Version Control with Git](#13-version-control-with-git)
14. [Import, Export, and Templates](#14-import-export-and-templates)
15. [How Appsmith Works (Concepts)](#15-how-appsmith-works-concepts)
16. [Troubleshooting](#16-troubleshooting)
17. [FAQ](#17-faq)
18. [Reference](#18-reference)

---

## 1. Quick Start

The fastest way to run Appsmith on your own machine is a single Docker container. Appsmith bundles everything it needs — the web editor, application server, real-time service, and databases — inside one image.

> [!IMPORTANT]
> You need [Docker](https://docs.docker.com/get-docker/) installed. Appsmith is distributed as a self-hosted container; there is no `npm install appsmith` or standalone binary. (Appsmith also offers a managed **Appsmith Cloud** at `login.appsmith.com` if you prefer not to self-host.)

=== "Docker (single command)"

    ```bash
    docker run -d \
      --name appsmith \
      -p 8080:80 \
      -v "$PWD/stacks:/appsmith-stacks" \
      -e APPSMITH_ENCRYPTION_PASSWORD="change-me-to-a-long-secret" \
      -e APPSMITH_ENCRYPTION_SALT="change-me-to-another-secret" \
      index.docker.io/appsmith/appsmith-ce:release
    ```

=== "Docker Compose"

    Create a `docker-compose.yml`:

    ```yaml
    services:
      appsmith:
        image: index.docker.io/appsmith/appsmith-ce:release
        container_name: appsmith
        ports:
          - "8080:80"
        environment:
          APPSMITH_ENCRYPTION_PASSWORD: change-me-to-a-long-secret
          APPSMITH_ENCRYPTION_SALT: change-me-to-another-secret
        volumes:
          - ./stacks:/appsmith-stacks
    ```

    Then start it:

    ```bash
    docker compose up -d
    ```

Watch the container come up:

```bash
docker logs -f appsmith
```

```text
PROCESS: editor - STATUS: RUNNING
PROCESS: server - STATUS: RUNNING
PROCESS: rts - STATUS: RUNNING
PROCESS: postgres - STATUS: RUNNING
PROCESS: redis - STATUS: RUNNING
```

When the processes report `RUNNING`, open **http://localhost:8080** in your browser and continue to [First-Run Setup](#3-first-run-setup).

> [!TIP]
> The `./stacks` volume (mounted at `/appsmith-stacks` inside the container) holds **all** your data: applications, datasource credentials, configuration, Git working copies, and logs. Keep it — deleting it deletes your apps. Back it up before upgrades. See the Admin Guide for backup/restore procedures.

> [!CAUTION]
> The `APPSMITH_ENCRYPTION_PASSWORD` and `APPSMITH_ENCRYPTION_SALT` values are used to encrypt your stored datasource credentials. If you lose or change them after creating datasources, Appsmith can no longer decrypt those credentials and you will have to re-enter them. Set them once, to long random strings, and store them somewhere safe.

---

## 2. Installation

Appsmith supports several installation methods. Docker is recommended for evaluation and most self-hosted deployments; Kubernetes (Helm) is recommended for production-grade, highly-available installs. This section covers the user-facing essentials — full deployment topology, sizing, and configuration are in the Admin Guide.

| Method | Best for | Notes |
| --- | --- | --- |
| **Docker** | Evaluation, single-server self-hosting (*recommended*) | One container, one volume. Covered above. |
| **Kubernetes (Helm)** | Production / high availability | `StatefulSet` + persistent volume; optional bundled or external databases. See Admin Guide. |
| **AWS AMI** | One-click AWS deployment | Pre-baked image from the AWS Marketplace. |
| **DigitalOcean / Heroku / Ansible** | Platform-specific automation | Deployment manifests live under `deploy/` in the source tree. |

### System requirements

| Resource | Minimum | Recommended |
| --- | --- | --- |
| CPU | 1 vCPU | 2+ vCPU |
| Memory | 2 GB | 4 GB+ (the Helm chart requests `3000Mi` per pod by default) |
| Disk | 10 GB | 20 GB+ (grows with apps, Git history, and logs) |
| Ports | `8080` (or your chosen host port) → container `80` | — |

> [!NOTE]
> Appsmith runs the JVM application server, a Node.js service, and one or more databases inside the single container, so memory matters. If the container is killed or restarts under load, increase its memory allocation and tune `APPSMITH_JAVA_ARGS` (see the Admin Guide's configuration reference).

### Choosing an image tag

| Tag | Meaning |
| --- | --- |
| `release` | Latest stable release (use this for self-hosting). |
| `latest` | Most recent build; may include unreleased changes. |
| `v1.x.x` | Pin to a specific version for reproducible deployments. |

```bash
# Pin to a specific version instead of `release`
docker pull appsmith/appsmith-ce:v1.50
```

### Upgrading

Pull a newer image and recreate the container against the **same** `/appsmith-stacks` volume:

```bash
docker compose pull
docker compose up -d
```

> [!IMPORTANT]
> Always back up the `stacks` directory before upgrading. Appsmith runs database schema migrations automatically on startup; a backup lets you roll back if anything goes wrong. The Admin Guide documents the migration and backup tooling in detail.

---

## 3. First-Run Setup

The first time you open Appsmith you create the **instance administrator** account.

- [ ] Open `http://localhost:8080` (or your server's address).
- [ ] On the welcome screen, enter your name, email, and a password. This becomes the first super-admin account for the instance.
- [ ] Choose your role and use case when prompted (optional; used for onboarding).
- [ ] You land in the **Applications** home page inside your first workspace.

> [!TIP]
> The first account created is the **instance super-admin** and gains access to **Admin Settings** (the gear/settings area), where you configure authentication, email, and instance-wide options. Subsequent users sign up (or are invited) as regular members.

After setup you can immediately:

- **Create an application** — click *New* → *Application* in a workspace.
- **Invite teammates** — from a workspace or application, share with their email and assign a role.
- **Configure sign-in** — from Admin Settings, enable Google/GitHub/OIDC SSO or disable open signup (see Admin Guide).

---

## 4. Core Concepts

Appsmith organizes everything into a small, consistent hierarchy. Learn these six nouns and the rest of the product falls into place.

| Concept | What it is |
| --- | --- |
| **Workspace** | A container for applications and members. Use one per team, client, or department. Permissions are managed at the workspace level. |
| **Application** | A single tool you build and publish. Has one or more pages, a set of datasources, queries, and JS objects. |
| **Page** | A screen within an application. Each page has its own canvas of widgets, and its own `onPageLoad` queries. |
| **Widget** | A UI element you drag onto the canvas — table, form, button, chart, input, etc. Widgets have **properties** (configured in the property pane) that you can hard-code or bind to data. |
| **Datasource** | A saved, reusable connection to a database, API, or service (e.g. "Production Postgres"). Credentials are stored encrypted. |
| **Query / Action** | An operation that runs against a datasource — a SQL statement, an API call, a Google Sheets read. Queries return data your widgets consume. |
| **JS Object** | A collection of JavaScript functions and variables (also called a "Collection of actions") that holds custom logic shared across a page. |

The mental model:

```text
Workspace
└── Application
    ├── Page 1
    │   ├── Widgets (Table, Form, Button, ...)
    │   ├── Queries  (SELECT * FROM users, ...)
    │   └── JS Objects (utils.formatName(), ...)
    ├── Page 2
    └── Datasources (shared across the application's pages)
```

Data flows **datasource → query → widget**, with **bindings** (`{{ }}`) gluing the pieces together, and the editor re-evaluating everything reactively as values change.

> [!NOTE]
> A **workspace** is sometimes referred to internally as an *organization*, and the term *tenant* appears in some instance-level settings. For everyday app building, "workspace" is the unit you'll interact with.

---

## 5. The App Editor Tour

When you open an application for editing, the URL looks like:

```text
/app/{application-slug}/{page-slug}-{pageId}/edit
```

The published (read-only) version of the same page is served from the same path **without** `/edit`:

```text
/app/{application-slug}/{page-slug}-{pageId}
```

The editor has four main regions:

| Region | Purpose |
| --- | --- |
| **Entity Explorer** (left) | A tree of your application: pages, widgets, queries, JS objects, and datasources. Click any entity to select and configure it. |
| **Canvas** (center) | The drag-and-drop surface where you place and arrange widgets. Switch between **Edit** and **Preview** modes. |
| **Property Pane** (right) | Configuration for the currently selected widget — its data, styles, and event handlers. |
| **Bottom Bar / Debugger** | Logs, errors, and query/JS responses. Your first stop when something doesn't evaluate. |

> [!TIP]
> Press the **Preview** toggle to interact with your app exactly as an end user would, without leaving the editor. The **Deploy** button publishes the current state to the viewer URL.

### Layout systems

Appsmith provides more than one way to arrange widgets:

- **Fixed layout** — pixel-positioned widgets on a grid (the classic experience).
- **Auto-layout** — responsive layout that reflows widgets across screen sizes.
- **Anvil** — the newer responsive layout system built on Sections and Zones with the modern widget set (WDS). Anvil emphasizes responsive, mobile-friendly design out of the box.

You choose a layout approach per application; the property pane and available widgets adapt accordingly.

---

## 6. Connecting Data Sources

A **datasource** is a saved connection. Create it once, then reference it from any number of queries in the application.

### Supported data sources

Appsmith ships first-class connectors ("plugins") for a wide range of databases, APIs, and services. Rather than a one-off integration each, they all follow the **same connect → query → bind** pattern, so once you've connected one you know them all.

| Category | Connectors |
| --- | --- |
| **Relational databases** | PostgreSQL, MySQL, Microsoft SQL Server, Oracle, Redshift, Snowflake, Databricks |
| **NoSQL / document** | MongoDB, ArangoDB, DynamoDB, Firestore, Elasticsearch |
| **Key-value / cache** | Redis |
| **APIs** | REST API, GraphQL |
| **Cloud storage / compute** | Amazon S3, AWS Lambda |
| **Productivity / SaaS** | Google Sheets, SMTP (email) |
| **AI / LLM** | OpenAI, Anthropic, Google AI, Appsmith AI |
| **Built-in** | JavaScript (no external datasource needed) |

> [!NOTE]
> If a service isn't in the list, you can almost always reach it through the **REST API** or **GraphQL** connector. Anything with an HTTP endpoint is connectable.

### Creating a datasource

1. In the Entity Explorer, click **+** next to **Datasources** (or *New* → *Datasource*).
2. Pick a connector (e.g. **PostgreSQL**).
3. Fill in the connection form. For a SQL database you typically supply:

   | Field | Example |
   | --- | --- |
   | Host | `db.internal.example.com` |
   | Port | `5432` |
   | Database name | `appdata` |
   | Username | `app_readonly` |
   | Password | `••••••••` |
   | SSL mode | `Require` / `Default` / `Disable` |

4. Click **Test** to verify connectivity, then **Save**.

> [!CAUTION]
> Datasource credentials are encrypted at rest using your instance's `APPSMITH_ENCRYPTION_PASSWORD`/`APPSMITH_ENCRYPTION_SALT`. Use a **least-privilege** database account (read-only where possible) for any datasource that backs a read-heavy dashboard.

> [!TIP]
> Appsmith can reach databases on the same private network as the container. For a database on your host machine from inside Docker, use `host.docker.internal` (macOS/Windows) as the host. For production, run Appsmith where it can route to your database over a private network.

### Authenticated REST and OAuth

For the **REST API** and **GraphQL** connectors you can configure base URL, default headers, query params, and an authentication scheme: none, Basic, Bearer token, API key, or OAuth 2.0 (authorization code / client credentials). Configure auth once on the datasource and every query inherits it.

> [!NOTE]
> A known community item ([#31059](https://github.com/appsmithorg/appsmith/issues/31059)) tracks the field ordering in the OAuth 2.0 datasource form (`expires_in` vs. `scope`). It does not affect functionality.

---

## 7. Writing Queries

A **query** (also called an **action**) runs an operation against a datasource and returns data. Each query belongs to a page and shows up in the Entity Explorer.

### Creating a query

1. Click **+** next to **Queries/JS** → choose a datasource.
2. Write the operation. For SQL, that's a statement:

   ```sql
   SELECT id, name, email, created_at
   FROM users
   WHERE status = 'active'
   ORDER BY created_at DESC
   LIMIT 50;
   ```

3. Click **Run** (or `Cmd/Ctrl + Enter`) to execute. The response appears in the bottom pane.

### Parameterizing queries with bindings

Queries become powerful when they read from widgets. Use `{{ }}` to inject values from the UI:

```sql
SELECT * FROM users
WHERE name ILIKE {{ '%' + SearchInput.text + '%' }}
LIMIT {{ Table1.pageSize }}
OFFSET {{ (Table1.pageNo - 1) * Table1.pageSize }};
```

> [!IMPORTANT]
> Appsmith parameterizes bound values as **prepared-statement** parameters for SQL datasources by default, which protects against SQL injection. Keep *Use prepared statements* enabled unless you have a specific reason to disable it — and if you disable it, never interpolate untrusted input directly into the statement.

### Running queries: on demand, on page load, and on events

A query can run:

- **Manually** — only when you call it (`MyQuery.run()`), e.g. from a button.
- **On page load** — automatically when the page opens. Toggle *Run query on page load* in the query settings. Appsmith resolves load order from the dependency graph.
- **From an event** — wired to a widget event such as a button's `onClick`.

```javascript
// In a Button widget's onClick event
{{ createUser.run() }}
```

### Query lifecycle callbacks

`run()` returns a promise, so you can chain success and failure handling:

```javascript
{{
  createUser.run()
    .then(() => {
      showAlert('User created', 'success');
      getUsers.run();          // refresh the table
      closeModal('NewUserModal');
    })
    .catch((e) => showAlert('Failed: ' + e.message, 'error'))
}}
```

> [!TIP]
> Common framework functions you'll use in events: `showAlert(message, type)`, `showModal(name)` / `closeModal(name)`, `navigateTo(page, params)`, `storeValue(key, value)`, `copyToClipboard(text)`, `download(data, name, type)`, and `resetWidget(name)`. These are available anywhere you write a binding.

---

## 8. Building the UI with Widgets

Widgets are the building blocks of your interface. Drag one from the widget panel onto the canvas, then configure it in the property pane.

### Widget catalog

Appsmith provides 50+ widgets. The most commonly used:

| Group | Widgets |
| --- | --- |
| **Buttons & actions** | Button, Button Group, Menu Button, Icon Button, Toolbar Buttons |
| **Inputs** | Input, Currency Input, Phone Input, Number Slider, Range Slider, Rich Text Editor, Code Scanner |
| **Selection** | Select, MultiSelect, Tree Select, Radio Group, Checkbox, Checkbox Group, Switch, Switch Group, Category Slider, Rating |
| **Date & time** | Date Picker |
| **Data display** | **Table**, List, JSON Form, Stats Box, Progress Bar, Circular Progress, Text |
| **Layout** | Container, Form, Tabs, Modal, Divider, Section, Zone (Anvil) |
| **Media** | Image, Video, Audio, Audio Recorder, Camera, Document Viewer, Icon |
| **Charts & maps** | Chart, Map, Map Chart |
| **Files** | File Picker |
| **Advanced** | Custom (embed your own HTML/JS), Iframe, IFrame, JSON Form |

> [!NOTE]
> Newer applications using the **Anvil** layout system use the **WDS** (Widget Design System) widget family — modern, responsive, theme-aware variants such as `WDSTable`, `WDSButton`, `WDSInput`, `WDSSelect`, and the `Section`/`Zone` layout primitives. Classic and WDS widgets offer overlapping capabilities; which set you see depends on the layout system the app uses.

### Configuring a widget

Each widget's property pane is organized into:

- **Data** — what the widget displays (often a `{{ }}` binding to a query).
- **General / Validation** — behavior, required flags, default values, visibility.
- **Events** — handlers like `onClick`, `onChange`, `onRowSelected`, `onSubmit`.
- **Style** — colors, fonts, borders, spacing (or theme-driven for WDS/Anvil).

### Spotlight: the Table widget

The Table is the workhorse of internal tools. Point its **Table Data** property at a query result:

```javascript
{{ getUsers.data }}
```

Then you get, for free:

- Sorting, search, filtering, and pagination (server-side or client-side).
- Per-column types: text, number, date, image, button, menu, checkbox, select, etc.
- Row selection (`Table1.selectedRow`, `Table1.selectedRows`).
- Inline editing with `onSubmit` events for write-back.
- Computed columns via `{{ }}` (e.g. format a currency, combine fields).

```javascript
// A computed "Full name" column
{{ currentRow.first_name + ' ' + currentRow.last_name }}
```

> [!TIP]
> Use the newer **Table** widget (internally `TableWidgetV2`) for new apps — it has richer column types, inline editing, and better performance than the legacy table.

> [!NOTE]
> A known community item ([#41734](https://github.com/appsmithorg/appsmith/issues/41734)) reports the required-field marker (`*`) not always rendering on required Select widgets. Validation still enforces the requirement; only the visual asterisk is affected in some cases.

---

## 9. Binding Data: The `{{ }}` Language

Bindings are the heart of Appsmith. Anywhere you see a field that accepts dynamic input, you can write JavaScript inside `{{ }}` and reference any widget, query, or JS object on the page.

### What you can reference

| Reference | Returns |
| --- | --- |
| `Query1.data` | The latest result of a query. |
| `Query1.isLoading` | `true` while the query is running. |
| `Widget1.text` / `.selectedRow` / `.selectedOptionValue` | The widget's current value/state. |
| `JSObject1.myFunction()` | The return value of a JS function. |
| `appsmith.user` | The signed-in user (`email`, `name`, roles). |
| `appsmith.store` | Values you've saved with `storeValue()`. |
| `appsmith.URL` | Current URL, query params, and path. |
| `appsmith.theme` | The active theme tokens. |

### Examples

```javascript
// Conditionally show a widget
{{ appsmith.user.email.endsWith('@yourcompany.com') }}

// Default a form field from the selected table row
{{ UsersTable.selectedRow.email }}

// Transform query data for a chart
{{ getSales.data.map(r => ({ x: r.month, y: r.total })) }}

// Disable a Submit button until the form is valid
{{ !NameInput.isValid || SubmitQuery.isLoading }}
```

### Reactive evaluation

Bindings are **reactive**: when any value a binding depends on changes, Appsmith automatically re-evaluates the binding and updates the UI — no manual refresh, no event wiring. Type into a search box and a table bound to a query that references it updates as the dependency graph propagates the change.

> [!IMPORTANT]
> Bindings run client-side in a sandboxed worker and must be **synchronous expressions** (for triggering side effects like `.run()`, use widget events). Keep heavy transformation logic in [JS Objects](#10-javascript-objects-and-custom-logic) rather than cramming it into a property field.

---

## 10. JavaScript Objects and Custom Logic

When a one-line binding isn't enough, write a **JS Object** — a named collection of JavaScript functions and variables you can call from anywhere on the page.

1. Click **+** next to **Queries/JS** → **New JS Object**.
2. Write functions:

```javascript
export default {
  // a reusable formatter
  fullName(row) {
    return `${row.first_name} ${row.last_name}`;
  },

  // an async workflow that orchestrates several queries
  async approve(requestId) {
    await updateRequest.run({ id: requestId, status: 'approved' });
    await notifyOwner.run({ id: requestId });
    showAlert('Request approved', 'success');
    return getРequestsTable.run?.() ?? getRequests.run();
  },

  // a plain variable, usable in bindings
  pageSize: 25,
};
```

3. Reference them in bindings or events:

```javascript
{{ JSObject1.fullName(UsersTable.selectedRow) }}
```

```javascript
// In a Button onClick
{{ JSObject1.approve(RequestsTable.selectedRow.id) }}
```

### Custom JavaScript libraries

Beyond your own JS Objects, you can install third-party JS libraries (e.g. a date or CSV library) into an application and call them from any binding. Manage them from the **Libraries** area of the editor (`/libraries`); they load into the same evaluation sandbox your bindings run in.

> [!TIP]
> Async functions in JS Objects can be marked to **run on page load** and can use `async/await` with `Query.run()`. Use them to encapsulate multi-step workflows (validate → write → notify → refresh) instead of stringing long `.then()` chains into a button.

---

## 11. Common Tasks (Recipes)

### Build a searchable, paginated table

1. Add an **Input** widget named `SearchInput`.
2. Create a query `getUsers` that references it:

   ```sql
   SELECT * FROM users
   WHERE name ILIKE {{ '%' + SearchInput.text + '%' }}
   ORDER BY created_at DESC;
   ```

3. Add a **Table** widget; set **Table Data** to `{{ getUsers.data }}`.
4. In `SearchInput`'s `onTextChanged`, run the query (debounced):

   ```javascript
   {{ getUsers.run() }}
   ```

### Create a record from a form

1. Add a **Form** with input widgets (`NameInput`, `EmailInput`).
2. Create an insert query:

   ```sql
   INSERT INTO users (name, email)
   VALUES ({{ NameInput.text }}, {{ EmailInput.text }});
   ```

3. On the Submit button's `onClick`:

   ```javascript
   {{ createUser.run().then(() => { getUsers.run(); resetWidget('NewUserForm', true); }) }}
   ```

### Edit a row inline and write back

1. Enable inline editing on the Table's editable columns.
2. On the Table's `onSubmit` (save) event, run an update keyed by the edited row:

   ```sql
   UPDATE users SET name = {{ UsersTable.updatedRow.name }}
   WHERE id = {{ UsersTable.updatedRow.id }};
   ```

### Show a confirmation modal before a destructive action

1. Add a **Modal** named `ConfirmDelete`.
2. Delete button `onClick`: `{{ showModal('ConfirmDelete') }}`.
3. Modal's confirm button `onClick`:

   ```javascript
   {{ deleteUser.run().then(() => { closeModal('ConfirmDelete'); getUsers.run(); }) }}
   ```

### Navigate between pages with context

```javascript
// Pass the selected user's id to a detail page
{{ navigateTo('UserDetail', { userId: UsersTable.selectedRow.id }) }}
```

```javascript
// On the detail page, read it back
{{ appsmith.URL.queryParams.userId }}
```

### Export table data to CSV

The Table widget includes a built-in download/export control; enable it in the table's properties. For custom exports:

```javascript
{{ download(JSON.stringify(getUsers.data), 'users.json', 'application/json') }}
```

---

## 12. Publishing and Sharing Apps

### Deploy

Click **Deploy** in the editor to publish the current edited state. This creates/updates the **published** version served at the viewer URL (`/app/{app-slug}/{page-slug}-{pageId}`). Edits you make afterward are not visible to viewers until you Deploy again.

### Share and permissions

- **Invite users** to the application or workspace by email and assign a role.
- **Roles** govern who can edit vs. only view the published app. (Granular, custom role-based access control is an Enterprise feature; CE provides core roles.)
- **Public apps** — you can make a published application accessible without login if your instance allows it.

### Embedding

Published apps can be embedded in other sites via an iframe. Embedding is governed by the instance's `APPSMITH_ALLOWED_FRAME_ANCESTORS` setting — by default Appsmith restricts which domains may frame it. Ask your administrator to allow your domain (see Admin Guide).

> [!TIP]
> Use the **Embed** option in app settings to generate the snippet and configure whether the embedded app shows navigation.

---

## 13. Version Control with Git

Appsmith applications can be connected to a Git repository, giving you branches, commits, history, and team collaboration with merge — the same workflow developers expect.

### Connect an application to Git

1. Open the app's **Git settings** (the Git icon in the editor).
2. Provide a repository URL and a deploy key (Appsmith generates an SSH key for you to add to your Git provider as a deploy key with write access).
3. Connect. Appsmith creates a working copy of the application as code in the repo.

### Everyday Git workflow

- **Commit** — save the current app state with a message.
- **Branch** — create a branch to work on a feature in isolation; each branch is an independent editable copy.
- **Merge** — open a merge from your branch into the base branch; resolve conflicts in the UI if they arise.
- **Pull / Deploy** — pull the latest changes from the remote; deploy promotes committed work.

> [!IMPORTANT]
> Git-connected apps store their working copies under the instance's Git storage directory (`/appsmith-stacks/git-storage` inside the container). This is part of the persistent volume, so it survives restarts but **must be included in backups**.

> [!NOTE]
> Continuous Delivery (auto-deploy from Git) and some advanced Git workflows are Enterprise features. Core connect/commit/branch/merge is available in CE.

---

## 14. Import, Export, and Templates

### Export and import applications

- **Export** an application to a JSON file from the application's menu. The export bundles pages, widgets, queries, JS objects, and datasource *configurations* (without secret credentials).
- **Import** a JSON file into a workspace to recreate the application. You'll be prompted to reconnect datasource credentials.

This is the simplest way to move an app between Appsmith instances (e.g. from a staging instance to production) without Git.

> [!TIP]
> **Partial import/export** lets you move just selected entities (specific queries, JS objects, or widgets) between applications — useful for sharing reusable building blocks.

### Templates and building blocks

Appsmith ships a gallery of **templates** — complete, ready-to-fork applications (admin panels, CRMs, dashboards) — and **building blocks** (pre-assembled widget groups). Start from a template to skip boilerplate, then point its queries at your own datasources.

---

## 15. How Appsmith Works (Concepts)

You don't need this section to build apps, but understanding the runtime helps you reason about performance and debugging. Deep architecture and internals are in the Admin Guide.

- **One application, one reactive graph.** Every binding, query, JS variable, and widget property is a node in a dependency graph. When a value changes, Appsmith recomputes exactly the downstream nodes that depend on it. This is why the UI updates "automatically."
- **Bindings run in a sandbox.** Your `{{ }}` expressions and JS Objects execute in a sandboxed web worker in the browser — not on the server — so they can't access the page's cookies or the host environment directly.
- **Queries run on the server.** When you call `Query.run()`, the request goes to the Appsmith server, which executes it against the datasource using the matching connector and returns the result. Credentials never reach the browser.
- **Autocomplete and linting.** The code editors offer field-aware autocomplete (powered by a background language service) and inline linting, so typos in bindings surface as you type.

> [!NOTE]
> Because evaluation is reactive and queries are server-executed, two performance levers matter most: keep page-load queries lean (return only the columns/rows you render), and avoid binding expensive transformations directly into widget properties that re-evaluate often — move them into JS Objects or push the work into the query (SQL `WHERE`/`LIMIT`).

---

## 16. Troubleshooting

### Error: `No data tree evaluator found`

**Cause:** The client-side evaluation worker hasn't finished initializing (often right after the editor loads, or after a worker crash).
**Solution:** Reload the editor page. If it persists, clear the browser cache / hard-reload, and check the browser console for worker errors.
**Prevention:** Avoid extremely large synchronous transformations in bindings that can stall the worker; keep heavy logic in JS Objects and let queries do data shaping.

### A binding shows `undefined` or an empty value

**Cause:** The referenced entity hasn't produced data yet (query not run, widget empty), or a field name is misspelled.
**Solution:** Open the **Debugger** (bottom bar) and inspect the entity. Confirm the query has run and returned the field you reference. Use optional chaining: `{{ getUser.data?.[0]?.email }}`.
**Prevention:** Set sensible defaults and guard against `null`/empty arrays in bindings.

### Query fails with a database/connection error

**Cause:** Wrong host/port/credentials, network isolation between the container and the database, or a missing SSL setting.
**Solution:** Open the datasource and click **Test**. From inside Docker, use `host.docker.internal` to reach a database on your host. Verify the database accepts connections from the Appsmith host's IP.
**Prevention:** Use a dedicated, least-privilege DB account and confirm network routing before building queries on top of the datasource.

### A query returns data, but the Table is empty

**Cause:** **Table Data** isn't bound to the query result, or the result shape isn't an array of objects.
**Solution:** Set Table Data to `{{ YourQuery.data }}`. If the connector returns a nested object, map it: `{{ YourQuery.data.rows }}`.
**Prevention:** Run the query and inspect the response shape in the Debugger before binding.

### Changes aren't visible to end users

**Cause:** You edited but didn't **Deploy**. The viewer serves the last deployed version.
**Solution:** Click **Deploy** to publish your edits.
**Prevention:** Remember the edit/deploy split — editing is private until you deploy.

### Datasource credentials stopped working after a restart/upgrade

**Cause:** `APPSMITH_ENCRYPTION_PASSWORD`/`APPSMITH_ENCRYPTION_SALT` changed, so stored credentials can no longer be decrypted.
**Solution:** Restore the original encryption values, or re-enter the datasource credentials.
**Prevention:** Set the encryption password/salt once to fixed secrets and never change them; store them with your other secrets.

### Can't embed the app in another site (blank iframe / CSP error)

**Cause:** The instance's `APPSMITH_ALLOWED_FRAME_ANCESTORS` doesn't include the embedding domain.
**Solution:** Ask your administrator to add your domain to the allowed frame ancestors (Admin Guide → configuration).
**Prevention:** Plan embedding domains with your administrator before building the embed.

### The app or editor is slow / the container restarts under load

**Cause:** Insufficient memory for the JVM server inside the container, or heavy page-load queries.
**Solution:** Increase the container's memory; trim page-load queries to only needed columns/rows; paginate large tables server-side.
**Prevention:** Size the host appropriately (see Admin Guide) and design queries to return small result sets.

### After Deploy, OAuth/Google login redirects fail

**Cause:** The OAuth redirect URI or custom domain isn't configured to match the deployed URL.
**Solution:** Have your administrator set the correct `APPSMITH_CUSTOM_DOMAIN` and OAuth client settings (Admin Guide → authentication).
**Prevention:** Configure the public domain and SSO before sharing the app externally.

> [!TIP]
> The **Debugger** (bottom bar) is your single most useful tool: it shows per-query responses, binding errors, and a live log. Open it first whenever something doesn't behave as expected.

---

## 17. FAQ

**Q: Do I need to know how to code to use Appsmith?**
You can build a lot with drag-and-drop widgets and the visual query editor. To go beyond CRUD, basic JavaScript inside `{{ }}` bindings and JS Objects unlocks the full power of the platform. SQL (or your datasource's query language) helps for data-heavy apps.

**Q: Is Appsmith free?**
The Community Edition is free and open-source under the Apache 2.0 license, and you can self-host it at no cost. Appsmith also offers a managed Cloud and an Enterprise Edition (paid) with SSO/SAML, granular access control, audit logs, and support.

**Q: Where is my data stored?**
Your *application definitions* and *encrypted datasource credentials* live inside Appsmith's bundled database (in the `/appsmith-stacks` volume). Your *actual business data* stays in your own connected datasources — Appsmith queries it on demand and doesn't copy it.

**Q: Can Appsmith connect to a database on my private network?**
Yes — run Appsmith where it can route to the database (same VPC/network). From a local Docker container to a host database, use `host.docker.internal` as the host.

**Q: Is my `{{ }}` JavaScript a security risk?**
Bindings execute in a sandboxed browser worker, and queries execute server-side with credentials that never reach the browser. Bound SQL values are sent as prepared-statement parameters by default to prevent injection.

**Q: How do I move an app from one instance to another?**
Export the app to JSON and import it on the target instance (reconnecting datasource credentials), or connect both to the same Git repository and pull.

**Q: How many users/apps can one instance handle?**
That depends on the host's resources and your apps' query load. Scale vertically (more CPU/memory) for a single container, or horizontally with the Kubernetes/Helm deployment. See the Admin Guide for sizing and autoscaling.

**Q: Can I customize the look and feel?**
Yes — applications have a theme (colors, fonts, border radius) you can edit, and the Custom widget lets you embed your own HTML/CSS/JS for anything the built-in widgets don't cover.

**Q: What's the difference between a Query and a JS Object?**
A **Query** runs against a datasource (SQL, API call, etc.) on the server. A **JS Object** is client-side JavaScript logic — formatters, validators, and async workflows that orchestrate queries. They work together.

**Q: My app needs a service Appsmith doesn't have a connector for. Now what?**
Use the **REST API** or **GraphQL** connector. Any HTTP-accessible service can be queried that way, with full control over headers, auth, and body.

**Q: Does editing an app affect what my users see immediately?**
No. Editing is private until you click **Deploy**. End users always see the last deployed version.

**Q: Can I version-control apps and review changes like code?**
Yes — connect the application to Git for branches, commits, history, and merges.

**Q: Is there a dark mode for the editor?**
A dark mode for the editor is a tracked community feature request ([#41858](https://github.com/appsmithorg/appsmith/issues/41858)). Individual applications can be themed independently of the editor chrome.

---

## 18. Reference

### Editor URL patterns

| Pattern | Meaning |
| --- | --- |
| `/applications` | Workspace home — list of applications. |
| `/app/{app}/{page}-{pageId}/edit` | Edit a page in the builder. |
| `/app/{app}/{page}-{pageId}` | View the published page. |
| `/libraries` | Manage installed JS libraries for the app. |

### Common framework functions (use in events and JS Objects)

| Function | Purpose |
| --- | --- |
| `MyQuery.run(params?)` | Execute a query; returns a promise. |
| `showAlert(message, type)` | Toast notification (`'success'`, `'error'`, `'warning'`, `'info'`). |
| `showModal(name)` / `closeModal(name)` | Open/close a Modal widget. |
| `navigateTo(pageOrUrl, params, target)` | Navigate within or outside the app. |
| `storeValue(key, value)` / `appsmith.store` | Persist and read client-side state. |
| `resetWidget(name, resetChildren)` | Reset a widget to defaults. |
| `copyToClipboard(text)` | Copy text. |
| `download(data, name, type)` | Trigger a file download. |
| `clearStore()` | Clear all stored values. |

### Global objects in bindings

| Object | Contains |
| --- | --- |
| `appsmith.user` | `email`, `name`, roles of the signed-in user. |
| `appsmith.store` | Values saved via `storeValue()`. |
| `appsmith.URL` | `pathname`, `queryParams`, `hash`, `host`. |
| `appsmith.theme` | Active theme tokens. |
| `appsmith.mode` | `EDIT` or `VIEW`. |

### Supported datasource connectors (25)

PostgreSQL · MySQL · Microsoft SQL Server · Oracle · Redshift · Snowflake · Databricks · MongoDB · ArangoDB · DynamoDB · Firestore · Elasticsearch · Redis · REST API · GraphQL · Amazon S3 · AWS Lambda · Google Sheets · SMTP · OpenAI · Anthropic · Google AI · Appsmith AI · SaaS · JavaScript (built-in)

### Keyboard shortcuts (selected)

| Shortcut | Action |
| --- | --- |
| `Cmd/Ctrl + Enter` | Run the focused query. |
| `Cmd/Ctrl + S` | Save (autosave is also continuous). |
| `Cmd/Ctrl + D` | Duplicate selected widget. |
| `Cmd/Ctrl + /` | Toggle comment in the code editor. |

### Where to go next

- **Self-hosting, configuration, security, scaling, and internals** → the companion **Appsmith Admin Guide**.
- **Official docs** → `docs.appsmith.com` · **Community** → `community.appsmith.com` · **Discord** → linked from the project README.

---

_Generated June 2026 from appsmithorg/appsmith at 293e1b6. AI-generated documentation. The library is checked by sampling (three repositories so far); this guide was not individually reviewed. Verify against the project before relying on it. Unofficial; not affiliated with or reviewed by the project._
