Â
Â
Â
Â
Â
Â
An opinionated cross-platform full-stack application template developed with Rust,
Cargo Mobile 2, Dioxus, Warp, Diesel, PostgreSQL, Supabase Auth, Bun and TailwindCSS.
Inspired by an attempt at rewriting in Rust the t4-app project.
- Install cargo-mobile2 using
cargo install --git https://github.com/tauri-apps/cargo-mobile2
- Install cargo-watch using
cargo install cargo-watch
- Install bun using
curl -fsSL https://bun.sh/install | bash
orpowershell -c "irm bun.sh/install.ps1 | iex"
- Install
@material-tailwind/html
usingbun install
- Watch and build TailwindCSS using
bun tailwind
- Create a new project on Supabase, this will be used for authentication, database integration & media storage.
- To setup Supabase Auth copy the
.env.example
file in a new.env
file and fill in theSUPABASE_URL
,SUPABASE_API_KEY
andSUPABASE_JWT_SECRET
fields with your Supabase credentials (found in the Supabase dashboard under project settings).
- To setup the database integration fill in the
DATABASE_URL
in the.env
file with a PostgreSQL connection string (you can use the one provided by Supabase):
DATABASE_URL="postgres://postgres.<name>:<password>@<domain>:<port>/<database>"
- Install the Diesel CLI using
cargo install diesel_cli --no-default-features --features postgres
. You could run into some issues linking the postgres library, in that case you should install thelibpq-dev
package (or Postgres for Windows) on your system and setup the correctrustc
linker path search in the.cargo/config.toml
file:
[target.x86_64-unknown-linux-gnu.pq]
rustc-link-search = ["/path/to/postgres/15/lib"]
rustc-link-lib = ["libpq"]
# or for Windows
[target.x86_64-pc-windows-msvc.pq]
rustc-link-search = ["C:\\path\\to\\postgres\\15\\lib"]
rustc-link-lib = ["libpq"]
- Run migrations using
bun migrate
or call directly thediesel
CLI inside theapi
folder. - Database access is gated to authenticated users but you can change that easily in the
api/src/handlers.rs
file by removing the JWT verification.
-
To setup Supabase Storage you should create two new buckets in the Supabase dashboard (e.g. a private bucket
images
and a public onepublic-images
), then upload a file to them (e.g.t5.png
). -
Make sure to allow read and/or write access to the private bucket for authenticated users, using Supabase RLS as follows:
- The example images (both public and authed) are instantiated inside the about page.
- Run the API server using
bun api
(orcargo run
inside theapi
folder).
All the below notes on various package versions and features are handled by the
bun web
,bun desktop
, andbun android
commands by automatically copying the correctCargo.toml
(.web
,.desktop
or.mobile
) file to the project root so beware of running multiple platorms at the same time.
To compile this you must switch on the
web
feature of thedioxus
package and remove themobile
one. Works only withoutopenssl
installed with thevendored
option in theCargo.toml
.
- Compile and run the web app using
bun web
(ordx serve
).
Works with
openssl
installed with thevendored
option and also without it (builds significantly faster both on Windows and Linux).
- Install all the necessary prerequisites for the
dioxus-cli
, you can find them here. - You should install
llvm
on your system withsudo apt install llvm-dev libclang-dev clang lib
on Linux,winget install LLVM.LLVM
on Windows orbrew install llvm
on MacOS to compile the desktop app. - You will also need to setup the
LIBCLANG_PATH
environment variable for Windows to point to the LLVM installation folder (e.g.C:\Program Files\LLVM\bin
) - Compile and run the desktop app using
bun desktop
(ordx serve --platform desktop
).
Works only with
openssl
installed with thevendored
option (requiresperl
of the UNIX flavour to build it, this means you cannot use the Windowsperl
version directly). Avoid spaces in the absolute path of the project folder, this will cause a linking error while buildingopenssl
.
- You have to run
cargo mobile init
to generate only the.cargo/config.toml
file and discard the other changes. If that errors out just create it with the following content to setup the linker for the Android targets:
[target.aarch64-linux-android]
linker = "/<absolute-path-to-home>/<path-to-sdk>/ndk/<ndk-version>/toolchains/llvm/prebuilt/linux-x86_64/bin/aarch64-linux-android<api-version>-clang"
[target.armv7-linux-androideabi]
linker = "/<absolute-path-to-home>/<path-to-sdk>/ndk/<ndk-version>/toolchains/llvm/prebuilt/linux-x86_64/bin/armv7-linux-android<api-version>-clang"
[target.i686-linux-android]
linker = "/<absolute-path-to-home>/<path-to-sdk>/ndk/<ndk-version>/toolchains/llvm/prebuilt/linux-x86_64/bin/i686-linux-android<api-version>-clang"
[target.x86_64-linux-android]
linker = "/<absolute-path-to-home>/<path-to-sdk>/ndk/<ndk-version>/toolchains/llvm/prebuilt/linux-x86_64/bin/x86_64-linux-android<api-version>-clang"
- You should also setup all the below environment variables in your terminal or in your
.bashrc
/.zshrc
file (or in the system environment for Windows) and installgcc-multilib
with apt to compile the Android app:
# These two variables depend on the architecture of the device
# and the API version you are targeting
export TARGET=aarch64-linux-android
export API=33
export JAVA_HOME=/usr/lib/jvm/java-17-openjdk-amd64
export ANDROID_HOME=$HOME/android
export ANDROID_SDK_ROOT=$ANDROID_HOME
export NDK_HOME=$ANDROID_HOME/ndk/<your-ndk-version>
export ANDROID_NDK_HOME=$NDK_HOME
export TOOLCHAIN=$ANDROID_NDK_HOME/toolchains/llvm/prebuilt/linux-x86_64
export AR=$TOOLCHAIN/bin/llvm-ar
export CC=$TOOLCHAIN/bin/$TARGET$API-clang
export AS=$CC
export CXX=$TOOLCHAIN/bin/$TARGET$API-clang++
export LD=$TOOLCHAIN/bin/ld
export RANLIB=$TOOLCHAIN/bin/llvm-ranlib
export STRIP=$TOOLCHAIN/bin/llvm-strip
export PATH=$JAVA_HOME/bin:$ANDROID_HOME/cmdline-tools/latest/bin:\
$TOOLCHAIN/bin:$NDK_HOME:$ANDROID_HOME/platform-tools:\
$ANDROID_HOME/tools:$ANDROID_HOME/tools/bin:$PATH
- Compile and run the Android app using
bun android
(orcargo android run
). - You can also debug the app wirelessly using
adb tcpip 5555
andadb connect <device-ip>:5555
with the device temporarily connected via USB (this works great on WSL). - Connect to the local API server using
adb reverse tcp:8000 tcp:8000
from the local machine.
- To produce optimized builds add the following code in the
.cargo/config.toml
file introduced above:
[profile.release]
opt-level = "z"
debug = false
lto = true
codegen-units = 1
panic = "abort"
strip = true
incremental = false
- If you want to use Github Actions to deploy the app (API, Web & Desktop) you should add the following secrets in the repository settings (the above optimizations are already included in the workflows):
API_URL (for the web app) -> update this after your API deployment
APP_URL (for the API) -> update this after your web deployment
SUPABASE_URL
SUPABASE_API_KEY
SUPABASE_JWT_SECRET
DATABASE_URL
- Install the
flyctl
CLI usingcurl -L https://fly.io/install.sh | sh
and login with your Fly.io account usingfly auth login
. - Create a new Fly app inside the project folder using
fly launch
and following the prompts, using the existingDockerfile
andfly.toml
files. - Deploy the API using
fly deploy
orbun deploy:api
. You can then change theAPI_URL
in the.env
file to the one deployed by Fly. - You can also deploy the API though Github Actions using the
./github/workflows/deploy-api.yml
workflow, adding to the repository secrets theFLY_API_TOKEN
key, generated withfly tokens create deploy -x 999999h
.
- To deploy the web app using Github Pages you have to choose in the repository settings under Pages the
gh-pages
branch. You should also set workflow permissions under the Actions settings toRead and write permissions
. - Change the
base_path
in theDioxus.pages.toml
file to match the name of your repository. - Remember to deploy your api with
APP_URL
set to your Github Pages domain (e.g.https://albbus-stack.github.io
) otherwise there will be CORS errors. - Configure the
.github/workflows/deploy-web.yaml
workflow to deploy on every push to themaster
branch or manually with theworkflow_dispatch
event.
The Github action for MacOS is not yet implemented. Linux is barely functioning since the built bundle has some bugs (e.g the installed .deb package searches assets in the folder where you call it and not globally). Windows is the only platform that bundles correctly for now.
- For Windows you can configure the
.github/workflows/windows.yaml
workflow to build and upload the.msi
installer in the action artifacts on every push to themaster
branch or manually with theworkflow_dispatch
event. - For Linux you can configure the
.github/workflows/linux.yaml
workflow to build and upload the.deb
package along with the dist folder in the action artifacts on every push to themaster
branch or manually with theworkflow_dispatch
event. - Currently
dx bundle
is being actively developed and is not yet ready for production use, so you should usedx build
if bundling fails on other platforms (this is not good since you need attach the entiredist
folder to your release build).
- You can build the Android app using the
bun build:android
command, this will generate various.apk
files in subfolders ofgen/android/app/build/outputs/apk/
for each ABI. - Generate a keystore file to sign the app using the
keytool
CLI as follows:
keytool -genkey -keystore release.keystore -alias alias_name -keyalg RSA -validity 10000
- You can then sign each generated
.apk
file using thejarsigner
CLI as follows:
jarsigner -keystore release.keystore ./path/to/apk alias_name
- After signing an
.apk
you can install the app on your device physically or usingadb install ./path/to/apk
(you should sign and install an.apk
compatible with the ABI of your device).