Develop locally

Develop your Appwrite functions locally to make code changes without redeploying your function on every code change and hot reload your code for faster testing.

Setup

We use Docker to replicate the production environment for the local deployment of functions. These can be executed locally with the CLI command, which requires initializing a project with an appwrite.json file and having local code to run the function locally. The CLI also supports various other CLI commands.

  1. Install the Docker CLI

  2. Ensure Docker is running in the background

  3. Install the Appwrite CLI

  4. Log in to your Appwrite account using appwrite login

  5. Initialize your project

  6. Initialize an Appwrite function and copy and paste your code

Develop

Use the appwrite run functions command to develop your function locally.

ParameterDescription
--portSet your function port; it defaults to 3000, or the closest available, i.e. 3001, 3002, etc.
--function-idSelect a function so you don't have to click through the list each time.
--user-id <user-id>Impersonates a user. Automatically sets x-appwrite-user-id and x-appwrite-user-jwt headers if the user exists.
--with-variablesSet production environment variables for your function. Do this only if your functions don't have production secrets to avoid security risks.
--no-reloadSet your functions to not hot reload. Any changes to your code won't cause your function to restart.
Shell
appwrite run functions --port 3000 --function-id "<FUNCTION_ID>"

 runtime   | entrypoint  | path                           | commands     
-----------|-------------|--------------------------------|--------------
 node-16.0 | src/main.js | functions/<FUNCTION_ID>      | npm install  

ℹ Info: If you wish to change your local settings, update the appwrite.json file and rerun the 'appwrite run' command.
♥ Hint: Permissions, events, CRON and timeouts dont apply when running locally.
ℹ Info: Pulling Docker image ...
♥ Hint: This may take a few minutes, but we only need to do this once.
ℹ Info: Building function using Docker ...
Preparing for build ...

Building ...


added 4 packages, and audited 5 packages in 2s


1 package is looking for funding
  run `npm fund` for details


found 0 vulnerabilities

Packing build ...

Build finished.

ℹ Info: Starting function using Docker ...
♥ Hint: Function automatically restarts when you edit your code.
✓ Success: Visit http://localhost:3000/ to execute your function.

This command helps you efficiently develop your Appwrite functions on your local machine. When developing your Appwrite function locally, it will receive headers like a function deployed to Appwrite.

Learn more about developing a function

Dynamic API keys

You can use headers like dynamic API keys in your function, which give you access to your project services and allow you to operate without sessions. To configure your dynamic API key scopes, modify the scopes in the appwrite.json file.

Learn more about dynamic API keys

Hot reload

By default, the Appwrite CLI hot-reloads your functions, which means you can update the function code and the changes will be applied automatically. How this happens differs between runtimes with compiled languages versus interpreted ones.

Because runtimes with compiled languages must translate the source code into machine code, the function must rebuild on change.

When the source code in a runtime with an interpreted languages is updated, the function only needs to restart with the updated file. However, if a dependency file for the interpreted language is updated, the function must rebuild to update the dependencies. Refer to the table below for the dependency files of each language.

 LanguageDependency File
Node.js logo Node.js logoNode.jspackage.json, package-lock.json
PHP logo PHP logoPHPcomposer.json, composer.lock
Python logo Python logoPythonrequirements.txt, requirements.lock
Ruby logo Ruby logoRubyGemfile, Gemfile.lock
Deno logo Deno logoDenoImport URLs
Go logo Go logoGogo.mod
Dart logo Dart logoDartPubspec.yaml
Swift logo Swift logoSwiftPackage.swift (Swift Package Manager Files)
.NET logo .NET logo.NET.nupkg (NuGet Packages)
Bun logo Bun logoBunpackage.json, package-lock.json, bun.lockb
Kotlin logo Kotlin logoKotlinJAR Files (Java ARchive)
Java logo Java logoJavaJAR Files (Java ARchive)
C++ logo C++ logoC++.h (Header Files)

Impersonate user

You can also impersonate a user when you develop a function locally. Impersonate a user using the --user-id <USER_ID> option to select a user you want to use for testing. This allows you to test if the user can perform specific actions, such as creating a document.

When using the --user-id <USER_ID> endpoint, the CLI will check and return an error if the user does not exist. But if a user does exist, a JWT token will be generated and last for 1 hour, similar to API tokens. If the user exists, the header x-appwrite-user-id will be set with the userId value, and the x-appwrite-user-jwt header will be set with the generated JWT token value.

Shell
appwrite run functions --user-id "<USER_ID>"

Push function

Once you've developed your function, push it by running the following CLI command

Shell
appwrite push functions