A Monorepo for My ( 🌏 Personal Website / 🔬 Academic Profile ) and { Other Related Projects }
See the code
Super opinionated, completely overkill.
git clone [email protected]:ttttonyhe/ouorz-mono.git
bun install
cd apps/main
Create a .env file with your configuration, see below for a list of environment variables used in this project:
bun run dev:main
Warning
Running WordPress in a Docker container is extremely slow on lower-spec machines
At least 1 GB of RAM without MySQL 8, or 2 GB of RAM with MySQL 8, is recommended
This project is wrapped up in a Docker container built based on the official WordPress Docker image: wordpress:php8.0-apache.
Each build outputs a static Docker image (similar to a typical containerized application) which means updating WordPress itself or adding new themes/plugins requires redeployment.
All uploads are stored in an external store (Qiniu, similar to AWS S3), therefore wp-content/uploads can be treated as temporary data.
main app uses WordPress REST API to fetch data, wordpress app functions as a headless CMS. The theme peg is used to customize the behaviour of the REST API endpoints, therefore peg/functions.php should be the main focus when it comes to the development of wordpress app.
Optionally, WORDPRESS_CONFIG_EXTRA can be set to include other configurations:
define("MYSQL_CLIENT_FLAGS", MYSQLI_CLIENT_SSL);ini_set("error_reporting", E_ALL & ~E_NOTICE);ini_set("display_errors","Off")define("WP_REDIS_HOST", "redis_database_host");define("WP_REDIS_PASSWORD", "redis_database_pwd");"define("WP_REDIS_PORT", "redis_database_port")docker build --tag ouorz-wordpress .
docker run -p 8080:80 \
-e WORDPRESS_DB_HOST=[dev_database_host] \
-e WORDPRESS_DB_USER=[dev_database_user] \
-e WORDPRESS_DB_PASSWORD=[dev_database_pwd] \
-e WORDPRESS_DB_NAME=[dev_database_name] \
-e WORDPRESS_DEBUG=true \
-e WORDPRESS_CONFIG_EXTRA="define('MYSQL_CLIENT_FLAGS', MYSQLI_CLIENT_SSL);" \
-e WORDPRESS_TABLE_PREFIX=[dev_database_prefix] \
ouorz-wordpress
This project is based on Umami
Follow the instructions here → to sign up for Maxmind GeoLite2, and retrieve a license key
git clone [email protected]:ttttonyhe/ouorz-mono.git
bun install
cd apps/analytics
Create a .env file with your configuration, see below for a list of environment variables used in this project:
bun run --filter '@ouorz/analytics' build-postgresql-client
bun run dev:analytics
A super opinionated front-end toolkit library

Storybook: https://ui.twilight-toolkit.ouorz.com →
Currently only available in React, Foundation/Adaptor implementation is coming soon.
Work in progress
Build system: Turborepo with Remote Caching
Package manager: Bun workspaces
Linter: Oxlint · Formatter: Oxfmt
Git hooks: Lefthook
bun run --filter @ouorz/main upgrade
bun run build:main
package.json should only contain development dependenciesOxlint and Oxfmt run once for the whole repository, so there is no per-package lint script to keep in sync:
bun run lint # report problems
bun run lint:fix # apply the fixes that are safe to apply
bun run format # format every file
bun run check # what CI runs
Solidity keeps its own toolchain, since Oxfmt does not read .sol files:
bun run lint:sol
bun run format:sol
The anti-slop and no-comment-walls rules live in tools/oxlint/. They are
vendored on purpose: edit them in place when a rule stops matching how the
project is written.
lefthook.yml holds every hook. Jobs run in parallel, are filtered by glob, and
re-stage whatever they fix, so a commit only pays for the file types it touches.
bunx lefthook install # after a fresh clone (bun install does this too)
bunx lefthook run pre-commit # try the hook without committing
LEFTHOOK=0 git commit # bypass the hooks once
Solidity keeps Prettier because Oxfmt does not read .sol; .prettierrc.mjs
exists for that alone and should never be pointed at the whole repository.
Not really following this though...

Test runner: Cypress
Start server:
bun run build:main
bun run start:main
# or
cd apps/main
bun run dev:test
Run tests:
bun run test:main
apps/main uses Cypress Dashboard, disable it by changing the configuration file accordingly.
Build then deploy the Docker image via apps/wordpress/Dockerfile.
Note: by default, the image listens on port 80, rather than the more common 8080
This project utilizes a combination of Server-side Rendering (SSR) and (On-demand) Incremental Static Generation (ISG):
bun run build:main
bun run start:main
bun run build:analytics
bun run start:analytics
To deploy the storybook, export it as a static web app:
bun run build:twilight:ui:storybook
Configuration file fly.toml can be found under apps/wordpress. Persistent storage should mount to /var/www/html/wp-content.
fly launch
fly secrets set \
WORDPRESS_DB_HOST=[dev_database_host] \
WORDPRESS_DB_USER=[dev_database_user] \
WORDPRESS_DB_PASSWORD=[dev_database_pwd] \
WORDPRESS_DB_NAME=[dev_database_name] \
WORDPRESS_DEBUG=false \
WORDPRESS_TABLE_PREFIX=[dev_database_prefix] \
fly deploy
Optionally, volumes with the same name can be created in multiple Fly.io regions which allows Fly to run one or more instances of the app in multiple regions:
fly volumes create ouorz_wordpress_wp_content --region yyz --size 1 --no-encryption
fly volumes create ouorz_wordpress_wp_content --region fra --size 1 --no-encryption
fly volumes create ouorz_wordpress_wp_content --region hkg --size 1 --no-encryption
fly scale count 3
Optionally, Fly.io offers full-managed Redis databases which can be created using the following commands:
fly redis create
Traffic is automatically routed through a private IPv6 address restricted to your Fly organization.
Make sure to set root directory path to apps/<project-name>, then update build command to the following:
cd ../.. && bun run build:<project-name>
Enabling diff-based deployment is highly recommended:
git diff --quiet HEAD^ HEAD ./
36 followers · starred Nov 2023
234 followers · starred Oct 2022
55 followers · starred Jul 2024
93 followers · starred Jan 2024
A Monorepo for My ( 🌏 Personal Website / 🔬 Academic Profile ) and { Other Related Projects }
See the code
Super opinionated, completely overkill.
git clone [email protected]:ttttonyhe/ouorz-mono.git
bun install
cd apps/main
Create a .env file with your configuration, see below for a list of environment variables used in this project:
bun run dev:main
Warning
Running WordPress in a Docker container is extremely slow on lower-spec machines
At least 1 GB of RAM without MySQL 8, or 2 GB of RAM with MySQL 8, is recommended
This project is wrapped up in a Docker container built based on the official WordPress Docker image: wordpress:php8.0-apache.
Each build outputs a static Docker image (similar to a typical containerized application) which means updating WordPress itself or adding new themes/plugins requires redeployment.
All uploads are stored in an external store (Qiniu, similar to AWS S3), therefore wp-content/uploads can be treated as temporary data.
main app uses WordPress REST API to fetch data, wordpress app functions as a headless CMS. The theme peg is used to customize the behaviour of the REST API endpoints, therefore peg/functions.php should be the main focus when it comes to the development of wordpress app.
Optionally, WORDPRESS_CONFIG_EXTRA can be set to include other configurations:
define("MYSQL_CLIENT_FLAGS", MYSQLI_CLIENT_SSL);ini_set("error_reporting", E_ALL & ~E_NOTICE);ini_set("display_errors","Off")define("WP_REDIS_HOST", "redis_database_host");define("WP_REDIS_PASSWORD", "redis_database_pwd");"define("WP_REDIS_PORT", "redis_database_port")docker build --tag ouorz-wordpress .
docker run -p 8080:80 \
-e WORDPRESS_DB_HOST=[dev_database_host] \
-e WORDPRESS_DB_USER=[dev_database_user] \
-e WORDPRESS_DB_PASSWORD=[dev_database_pwd] \
-e WORDPRESS_DB_NAME=[dev_database_name] \
-e WORDPRESS_DEBUG=true \
-e WORDPRESS_CONFIG_EXTRA="define('MYSQL_CLIENT_FLAGS', MYSQLI_CLIENT_SSL);" \
-e WORDPRESS_TABLE_PREFIX=[dev_database_prefix] \
ouorz-wordpress
This project is based on Umami
Follow the instructions here → to sign up for Maxmind GeoLite2, and retrieve a license key
git clone [email protected]:ttttonyhe/ouorz-mono.git
bun install
cd apps/analytics
Create a .env file with your configuration, see below for a list of environment variables used in this project:
bun run --filter '@ouorz/analytics' build-postgresql-client
bun run dev:analytics
A super opinionated front-end toolkit library

Storybook: https://ui.twilight-toolkit.ouorz.com →
Currently only available in React, Foundation/Adaptor implementation is coming soon.
Work in progress
Build system: Turborepo with Remote Caching
Package manager: Bun workspaces
Linter: Oxlint · Formatter: Oxfmt
Git hooks: Lefthook
bun run --filter @ouorz/main upgrade
bun run build:main
package.json should only contain development dependenciesOxlint and Oxfmt run once for the whole repository, so there is no per-package lint script to keep in sync:
bun run lint # report problems
bun run lint:fix # apply the fixes that are safe to apply
bun run format # format every file
bun run check # what CI runs
Solidity keeps its own toolchain, since Oxfmt does not read .sol files:
bun run lint:sol
bun run format:sol
The anti-slop and no-comment-walls rules live in tools/oxlint/. They are
vendored on purpose: edit them in place when a rule stops matching how the
project is written.
lefthook.yml holds every hook. Jobs run in parallel, are filtered by glob, and
re-stage whatever they fix, so a commit only pays for the file types it touches.
bunx lefthook install # after a fresh clone (bun install does this too)
bunx lefthook run pre-commit # try the hook without committing
LEFTHOOK=0 git commit # bypass the hooks once
Solidity keeps Prettier because Oxfmt does not read .sol; .prettierrc.mjs
exists for that alone and should never be pointed at the whole repository.
Not really following this though...

Test runner: Cypress
Start server:
bun run build:main
bun run start:main
# or
cd apps/main
bun run dev:test
Run tests:
bun run test:main
apps/main uses Cypress Dashboard, disable it by changing the configuration file accordingly.
Build then deploy the Docker image via apps/wordpress/Dockerfile.
Note: by default, the image listens on port 80, rather than the more common 8080
This project utilizes a combination of Server-side Rendering (SSR) and (On-demand) Incremental Static Generation (ISG):
bun run build:main
bun run start:main
bun run build:analytics
bun run start:analytics
To deploy the storybook, export it as a static web app:
bun run build:twilight:ui:storybook
Configuration file fly.toml can be found under apps/wordpress. Persistent storage should mount to /var/www/html/wp-content.
fly launch
fly secrets set \
WORDPRESS_DB_HOST=[dev_database_host] \
WORDPRESS_DB_USER=[dev_database_user] \
WORDPRESS_DB_PASSWORD=[dev_database_pwd] \
WORDPRESS_DB_NAME=[dev_database_name] \
WORDPRESS_DEBUG=false \
WORDPRESS_TABLE_PREFIX=[dev_database_prefix] \
fly deploy
Optionally, volumes with the same name can be created in multiple Fly.io regions which allows Fly to run one or more instances of the app in multiple regions:
fly volumes create ouorz_wordpress_wp_content --region yyz --size 1 --no-encryption
fly volumes create ouorz_wordpress_wp_content --region fra --size 1 --no-encryption
fly volumes create ouorz_wordpress_wp_content --region hkg --size 1 --no-encryption
fly scale count 3
Optionally, Fly.io offers full-managed Redis databases which can be created using the following commands:
fly redis create
Traffic is automatically routed through a private IPv6 address restricted to your Fly organization.
Make sure to set root directory path to apps/<project-name>, then update build command to the following:
cd ../.. && bun run build:<project-name>
Enabling diff-based deployment is highly recommended:
git diff --quiet HEAD^ HEAD ./
36 followers · starred Nov 2023
234 followers · starred Oct 2022
55 followers · starred Jul 2024
93 followers · starred Jan 2024