Last updated July 11, 2026
Deployment
2 minutes read
folio.md produces plain HTML, CSS, and JS in dist/, ready to serve from GitHub Pages or GitLab Pages.
Build
If you installed folio as a dependency via folio init:
bun run folio:build # bun
npm run folio:build # npm
yarn folio:build # yarnIf you cloned the folio.md repository directly:
bun run build # bun
npm run build # npm
yarn build # yarnThe link validator runs automatically before every build. When you install folio.md as a dependency, it runs through folio:build. When you work in the repository directly, it runs through bun run build. It fails the build at exit code 1 on broken internal links and dead anchor fragments. Dead external URLs emit a warning but don’t fail the build.
If you cloned the folio.md repository directly, you can also run the link validator without a full build:
bun run validate-linksWhen you install folio.md as a dependency, this standalone command isn’t available. Link validation runs only as part of folio:build.
Deploying to GitHub pages
Add a workflow at .github/workflows/deploy.yml. Choose the tab for your package manager:
Bun
name: Deploy to GitHub Pages
on:
push:
branches: [master]
permissions:
contents: read
pages: write
id-token: write
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0 # needed for "last updated" git dates
- uses: oven-sh/setup-bun@v2
- run: bun install
- run: bun run build
- uses: actions/upload-pages-artifact@v3
with:
path: dist
deploy:
needs: build
runs-on: ubuntu-latest
environment:
name: github-pages
url: ${{ steps.deployment.outputs.page_url }}
steps:
- uses: actions/deploy-pages@v4
id: deploymentnpm
name: Deploy to GitHub Pages
on:
push:
branches: [master]
permissions:
contents: read
pages: write
id-token: write
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0
- uses: actions/setup-node@v4
with:
node-version: 20
- run: npm install
- run: npm run build
- uses: actions/upload-pages-artifact@v3
with:
path: dist
deploy:
needs: build
runs-on: ubuntu-latest
environment:
name: github-pages
url: ${{ steps.deployment.outputs.page_url }}
steps:
- uses: actions/deploy-pages@v4
id: deploymentyarn
name: Deploy to GitHub Pages
on:
push:
branches: [master]
permissions:
contents: read
pages: write
id-token: write
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0
- uses: actions/setup-node@v4
with:
node-version: 20
- run: yarn
- run: yarn build
- uses: actions/upload-pages-artifact@v3
with:
path: dist
deploy:
needs: build
runs-on: ubuntu-latest
environment:
name: github-pages
url: ${{ steps.deployment.outputs.page_url }}
steps:
- uses: actions/deploy-pages@v4
id: deploymentDeploying to GitLab pages
Add a pipeline at .gitlab-ci.yml:
Bun
pages:
image: oven/bun:latest
script:
- bun install
- bun run build
- mv dist public # GitLab Pages expects output in public/
artifacts:
paths:
- public
rules:
- if: $CI_COMMIT_BRANCH == "master"npm / yarn
pages:
image: node:20
script:
- npm install # or: yarn
- npm run build # or: yarn build
- mv dist public
artifacts:
paths:
- public
rules:
- if: $CI_COMMIT_BRANCH == "master"Custom server
Copy dist/ to any static file host. With nginx:
server {
listen 80;
root /var/www/my-docs/dist;
index index.html;
location / {
try_files $uri $uri/ $uri.html =404;
}
}