QMK/Vial Firmware Build API - Containerized keyboard firmware build service
🌐 English | 🇯🇵 日本語
GPK FWMaker is a containerized service that provides a REST API for generating QMK/Vial keyboard firmware. It automates the entire process from keyboard files to firmware compilation.
- QMK/Vial Firmware Build - Automated building via API
- File Conversion - KLE JSON → QMK/Vial, Vial → C keymap
- Keyboard File Generation - Automatic project file creation
- Vial Unique ID Generation - ID generation for Vial projects
- Full Docker Support - Ready-to-use containerized environment
- Complete TypeScript Migration - Enhanced type safety and code quality
- Vitest Testing Environment - Comprehensive API testing setup
- Docker Environment Verified - Production-ready deployment
- Quality Management System - Automated checks and test execution
- Docker Desktop installed
Download: https://www.docker.com
# Clone from GitHub
git clone https://github.com/darakuneko/gpk_fwmaker.git
cd gpk_fwmaker
# Or download ZIP
# https://github.com/darakuneko/gpk_fwmaker/archive/refs/heads/main.zip
# Build Docker image
docker compose build
# Start services
docker compose up -d
# Check service status
curl http://127.0.0.1:3123/
# → Returns "GPK FWMaker\!"
# Get QMK tags list
curl http://127.0.0.1:3123/tags/qmk
# → Returns ["0.29.4", "0.29.3", ...]
# QMK firmware build
curl -X POST -H "Content-Type: application/json" \
-d '{"kb": "reviung/reviung41", "km": "default", "tag": "0.19.3"}' \
http://127.0.0.1:3123/build/qmk
# Vial firmware build
curl -X POST -H "Content-Type: application/json" \
-d '{"kb": "reviung/reviung41", "km": "vial"}' \
http://127.0.0.1:3123/build/vial
After startup, a GPKFW
folder is automatically created in your home directory:
GPKFW/
├── keyboards/ # Keyboard files location
├── firmware/ # Generated firmware files
└── generated/ # Auto-generated files
Examples:
- Windows:
C:\\Users\\[username]\\GPKFW
- macOS:
/Users/[username]/GPKFW
- Linux:
/home/[username]/GPKFW
Base URL: http://127.0.0.1:3123
curl -X POST -H "Content-Type: application/json" \
-d '{"kb": "reviung/reviung41", "km": "default", "tag": "0.19.3"}' \
http://127.0.0.1:3123/build/qmk
- kb (required): Keyboard name
- km (required): Keymap name
- tag (required): QMK version tag
curl -X POST -H "Content-Type: application/json" \
-d '{"kb": "reviung/reviung41", "km": "vial"}' \
http://127.0.0.1:3123/build/vial
- kb (required): Keyboard name
- km (required): Keymap name
- commit (optional): Vial commit specification
curl -X POST -H "Content-Type: application/json" \
-d '{"fw": "custom", "kb": "my_keyboard", "km": "default"}' \
http://127.0.0.1:3123/build/custom
curl http://127.0.0.1:3123/tags/qmk
# → ["0.29.4", "0.29.3", "0.29.2", ...]
# QMK keyboards list
curl http://127.0.0.1:3123/list/qmk
# Vial keyboards list
curl http://127.0.0.1:3123/list/vial
curl http://127.0.0.1:3123/generate/vial/id
# → "0x12345678"
const formData = new FormData()
formData.append('kle', kleJsonFile)
formData.append('params', JSON.stringify({
kb: 'my_keyboard',
mcu: 'atmega32u4',
user: 'username',
vid: '0xFEED',
pid: '0x0001',
option: 1, // 0: QMK, 1: Vial, 2: via.json only
rows: 'GP0,GP1,GP2,GP3',
cols: 'GP4,GP5,GP6,GP7'
}))
fetch('http://127.0.0.1:3123/convert/kle/qmk', {
method: 'POST',
body: formData
})
const formData = new FormData()
formData.append('info', infoJsonFile)
formData.append('kle', kleJsonFile)
fetch('http://127.0.0.1:3123/convert/via/json', {
method: 'POST',
body: formData
})
const formData = new FormData()
formData.append('vial', vialJsonFile)
fetch('http://127.0.0.1:3123/convert/vial/json', {
method: 'POST',
body: formData
})
# Update QMK repository
curl http://127.0.0.1:3123/update/repository/qmk
# Update Vial repository
curl http://127.0.0.1:3123/update/repository/vial
curl -X POST -H "Content-Type: application/json" \
-d '{"kb": "my_keyboard", "mcu": "atmega32u4", "layout": "60_ansi", "user": "username"}' \
http://127.0.0.1:3123/generate/qmk/file
cd server
# Install dependencies
npm install
# TypeScript type checking
npm run type-check
# Run tests
npm run test
# Linting
npm run lint:ts
# Build
npm run build
# Start development server
npm run dev
# Comprehensive quality check (type check + linting)
npm run check
# Run tests
npm run test
# Run tests with coverage
npm run test:coverage
# Unit tests
npm run test:unit
# API tests
npm run test:api
# Watch mode
npm run test:watch
# UI dashboard
npm run test:ui
gpk_fwmaker/
├── Dockerfile # Docker configuration
├── compose.yml # Docker Compose configuration
├── server/ # Node.js API server
│ ├── src/
│ │ ├── app.ts # Express main application
│ │ ├── command.ts # QMK/Vial command execution
│ │ └── vial2c/
│ │ └── vial2c.ts # Vial→C keymap conversion
│ ├── tests/ # Test suite
│ ├── dist/ # Build output
│ └── tsconfig.json # TypeScript configuration
└── firmware-scripts/ # Python conversion scripts
- Backend: Node.js + Express + TypeScript
- Scripts: Python + Flask
- Testing: Vitest + SuperTest
- Container: Docker + Docker Compose
- Build Tools: TypeScript Compiler
- Quality Management: ESLint + TypeScript
error: branch 'x.x.x' not found.
Solution: Update repository
curl http://127.0.0.1:3123/update/repository/qmk
Solution: Ensure Docker Desktop is running
Solution: Verify port 3123 is not in use
lsof -i :3123
GPK FWBuilder
https://github.com/darakuneko/gpk_fwbuilder
Firmware Scripts by zykrah
https://github.com/zykrah/firmware-scripts
Buy me a coffee
Amazon Wishlist | Ko-fi
This project is released under the MIT License.
GPK FWMaker - Making QMK/Vial firmware generation easier
Made with ❤️ by darakuneko