Skip to content


Repository files navigation

Zoonk Banner

WARNING: This software is still in development and not ready for production. DO NOT USE IT IN PRODUCTION YET. The current version will break when v1.0 is released. This README will be updated when it's ready for production.

Open-source alternative to create interactive courses like Duolingo.
Learn more »

Roadmap · Community

Table of Contents

About this project

Interactive learning is more effective than traditional methods. Learners remember 10% of what they hear, 20% of what they read but 80% of what they see and do. That's why 34 hours of Duolingo are equivalent to a full university semester of language education.

We love Duolingo. We think those kinds of interactive experiences should be used in more fields. That's why we're building Zoonk, an open-source platform to create interactive courses like Duolingo.

Tech stack

Getting started

Follow the instructions below to get Zoonk up and running on your local machine. We have a Dockerfile for deploying our demo app to Fly. For using Docker locally, see this.


  • Elixir 1.17+ and Erlang 26+. Run elixir -v to find your current version for Elixir and Erlang.
  • Hex: mix local.hex.
  • Phoenix: mix archive.install hex phx_new.
  • PostgreSQL 15+: PostgreSQL.
  • (Linux users only): inotify-tools.

Local development

  • Run mix setup to install dependencies and set up the database and assets.
  • Run mix seed to fetch initial data to the database (See options).
  • Run mix phx.server to start a development server.
  • Run mix test to run tests.
  • Run mix ci to run code quality checks.
  • Run mix locale to update translation files.

SSL on localhost

Prefer to do local development using SSL to resemble production as much as possible. You can use mkcert to generate a certificate. After you install mkcert, follow the steps below:

  • Create a cert directory under priv: mkdir priv/cert.
  • Generate a new certificate: mkcert -key-file priv/cert/selfsigned_key.pem -cert-file priv/cert/selfsigned.pem localhost zoonk.test "*.zoonk.test" apple.test.
  • Run mkcert -install to install the certificate in the system trust store.
  • You may also need to enable Allow invalid certificates for resources loaded from localhost on Google Chrome flags.
  • Restart your local server: mix phx.server. You may also need to restart your browser.

You also need to make sure your machine maps localhost to a test domain (we're using zoonk.test for this guide). dnsmasq allows you to resolve domains to your local machine without having to change your /etc/hosts file. To install dnsmasq:

brew install dnsmasq

# Create a configuration directory
mkdir -pv $(brew --prefix)/etc/

# Set up your domains
echo 'address=/zoonk.test/' >> $(brew --prefix)/etc/dnsmasq.conf
echo 'address=/.zoonk.test/' >> $(brew --prefix)/etc/dnsmasq.conf
echo 'address=/apple.test/' >> $(brew --prefix)/etc/dnsmasq.conf

# Add dnsmasq to your resolver
sudo mkdir -v /etc/resolver
sudo bash -c 'echo "nameserver" > /etc/resolver/zoonk.test'
sudo bash -c 'echo "nameserver" > /etc/resolver/apple.test'

# Start dnsmasq
sudo brew services start dnsmasq

That's it! You can now start your local server (mix phx.server) and test your domains using:


We're using Resend to send emails. To make it work in production, you need to set the following environment variables on your server:

  • RESEND_API_KEY: Your Resend API key.


By default, we upload files to your local server and store them in the priv/static/uploads directory. However, we also support uploading files to Cloudflare Images. To use Cloudflare Images, you'll need to set the following environment variables on your server:

  • CLOUDFLARE_ACCOUNT_ID: Your Cloudflare account ID. You can find it on Cloudflare Dashboard > Images > Overview.
  • CLOUDFLARE_ACCOUNT_HASH: Your Cloudflare account hash. You can find it on Cloudflare Dashboard > Images > Overview.
  • CLOUDFLARE_API_TOKEN: Your Cloudflare API token. You can create a token on Cloudflare Dashboard > My Profile > API Tokens.