This monorepo contains code for most of BlueDot Impact's custom software. Reading this README carefully can save you a lot of time.
This includes:
- availability: Collect time availability information from users
- meet: Record meeting attendance, and host meetings with the Zoom Web SDK
- login: A custom build of Keycloak
- login-account-proxy: An app for setting up users in Keycloak from Bubble
- miniextensions-proxy (forms.bluedot.org): Host forms on a custom domain
- posthog-proxy (analytics.k8s.bluedot.org): Reverse proxy to send analytics to PostHog
- infra: Deploying the above applications on Kubernetes
The following key parts of our software are not in this repository because they are built in 3rd party services that are hard to open-source the code for:
- Public website (bluedot.org, aisafetyfundamentals.com, biosecurityfundamentals.com etc.): Wordpress
- Course hub: Bubble
- Application forms: MiniExtensions
- Apply short links: Short.io
- Primary database: Airtable
The following key parts of our software are not in this repository because they use substantially different toolchains, and are a pain to set up in a monorepo:
- Various Airtable extensions
- Keycloak theme
- Airtable standards
We welcome contributions! To help improve BlueDot Impact's software:
For simple edits e.g. typos or editing documentation, you should be able to search for the text in this repository and make edits in the GitHub UI.
For more complex edits, check you have the core skills to contribute, then follow the developer setup instructions below.
If you run into any difficulties, raise an issue or contact us.
What if I want to use BlueDot Impact's software myself?
You're very welcome to use and adapt our software for your own purposes, subject to the repository license. In general most of our apps are packaged as Docker containers, and most of our libraries are TypeScript NPM packages.There isn't yet extensive documentation on using our software for your own purposes. We'd be happy would accept contributions that make it easier for others to use our software. This could be by improving the way apps are structured or adding documentation.
How will my contribution be handled?
Our general principle for reviewing contributions is 'does this make things better' rather than 'is this perfect'. We'll generally try to give you feedback, but given our limited resources we sometimes may not always be able to do this.When contributing, you agree that we can use your contribution how we see fit, and you relinquish any copyright, patent, moral or other intellectual property rights in your contribution.
We recommend most contributors learn how to:
- Navigate their terminal and shell
- Contribute code on GitHub
- Read and write TypeScript code
- Use the basics of NPM and Node.js
- (recommended, macOS only) Install Homebrew
- Install Git
- On macOS with Homebrew:
brew install git
- On Ubuntu Linux:
sudo apt install -y git-all
- On macOS with Homebrew:
- Install Node.js 22
- On macOS with Homebrew:
brew install node
- On Ubuntu Linux:
curl -fsSL https://deb.nodesource.com/setup_22.x | sudo -E bash - && sudo apt-get install -y nodejs
- On macOS with Homebrew:
- Install Docker client. NB: NOT Docker Desktop.
- On macOS with Homebrew:
brew install docker
- On Ubuntu Linux: instructions
- On macOS with Homebrew:
- Install and configure a container runtime.
- On macOS with Homebrew:
brew install colima && brew services start colima && docker context use colima
- On Ubuntu Linux: already installed with client
- Other platforms: Docker Engine (NB: NOT Docker Desktop) or Podman
- On macOS with Homebrew:
- Install kubectl.
- On macOS with Homebrew:
brew install kubectl
- On Ubuntu Linux: instructions
- On macOS with Homebrew:
- (recommended) Install Visual Studio Code
- On macOS with Homebrew:
brew install --cask visual-studio-code
- On macOS with Homebrew:
- Clone this repository
- To clone the main repo (not a fork):
git clone [email protected]:bluedotimpact/bluedot.git
- To clone the main repo (not a fork):
- Change directory into the cloned repository, and run
npm install
Then find the app or library you want to contribute to. It should follow the general package structure. Usually this means you can change directory into the relevant folder, put any necessary values in .env.local
(if present), before editing code in src
, run
npm run start
or
npm run test
Some packages have their own README with further developer setup instructions specific to that app, plus useful information about how the app works. Read this!
Over time other people will make changes to the repository. Usually to get up to date with those changes, you'll need to pull the latest changes from the master branch, then re-run
npm install
This repository is split up into packages in the folders:
libraries
: code that is reused or shared across applicationsapps
: final products that actually get deployed, usually as web services
For example, the shared UI code for common components like buttons is a library. This would be consumed by multiple apps, such as the time availability form.
Inside each package folder, the common files you'll find are:
- (always)
package.json
: defines the NPM scripts, dependencies, and sometimes other package configuration. Thepackage.json
should usually identify the entrypoint (for libraries) or have at least a start script (for apps). Common scripts include:npm run start
: Start the application locally. The port should usually be printed to the terminal, and then you can visitlocalhost:<port>
in your browser e.g.localhost:8000
.npm run test
: Run automated tests, usually defined the files ending in.test.ts
or.test.tsx
. Most packages use vitest - see the vitest CLI docs for help.npm run test:watch
: Run the automated tests in an interactive watch mode. This runs the relevant tests automatically each time you edit the code.npm run lint
: Check for lint issues. Visual Studio Code should usually highlight these for you already.npm run build
: Build the application. This usually finds any type errors, which Visual Studio Code should usually highlight for you already.npm run postinstall
: Perform any extra steps to setup the application for development. Usually things like creating configuration files for local development. You usually don't need to run this manually, as it runs when you runnpm install
.npm run deploy:prod
: Actually deploy the app into the production (real-world) environment. You usually don't need to run this manually, as it is run by CD tooling when you merge your changes into the master branch.
README.md
: documentation to explain what the package does, how to use it, and how to contributesrc
: most of the code usually lives here. You usually want to edit files in this folder.pages
: pages in the web app. For examplepages/some-page.tsx
usually corresponds toapp.bluedot.org/some-page
. Theapi
folder contains API routes rather than webpages (learn more in the Next.js docs).components
: components reused within the web app. If the component is likely to be useful for multiple applications, consider moving it to theui
package.lib
: helper scripts for use around the application, that aren't componentsindex.ts
: usually the entrypoint, i.e. what runs when starting or deploying an app, or the what is imported when importing a library.public
: static files for web hosting directly, usually fonts or images
.env.*
: environment files, usually to set secrets or configuration..env.local
: for local development, e.g. when runningnpm run start
. This isn't synced to git, so you can put real secrets in here. If you have issues with your environment, try deleting this file and runningnpm install
again (maybe save the values first if they're important secrets!) - this should usually replace it with the template file..env.local.template
: intended to help people create their own.env.local
file. This is synced to git, so you should only put example or non-secret values here..env.test
: for the test environment, e.g. when runningnpm run test
.
tools
: custom tools helpful for developing the app, often referred to by NPM scripts.Dockerfile
: (apps only) code to help transform the package into a Docker container to be easily deployed.dist
,.turbo
: built or transformed outputs are put here. You can usually ignore this folder.node_modules
: any special dependencies for this specific package, that can't be put at the workspace root usually because of clashing versions. You can usually ignore this folder.
In terms of tools and external libraries, we usually use:
- Coding language: TypeScript
- Script management: NPM
- Custom dev tooling: Node.js or Bash (in the
tools
folder) - Databases: Airtable (via airtable-ts) or Postgres (via kysely and kanel)
- APIs: JSON via REST. Use path parameters and request bodies to send information. Web services should respond with an X-BlueDot-Version header in the format
yyyyMMdd.hhmmss.git_short_hash
(via environment variableVERSION_TAG
). - Authentication: JSON web tokens, with sign-in via Open ID Connect (OIDC)
- Linting tool: eslint
- Testing framework: vitest
- Web applications
- Front-end library: React.js
- Framework: Next.js, usually using the path router and avoiding SSR
- Styling: Tailwind CSS
- Components: Our own ui or @adobe/react-spectrum
className
util: clsx- Global state store: zustand
- Schema validation: zod
- Infrastructure management: Pulumi
- Reverse proxies: nginx
- CI and CD: GitHub Actions via .github
- Deployment: Docker on K8s via infra
In general, we try to keep to the above structure and tools as much as possible between packages. This reduces the mental effort required to switch between working on different packages, and eases maintenance burden. We're fans of boring technology.