Thank you for your interest in contributing to lloyal.node! This guide covers development setup, testing, and the release process.
- Node.js 22 or 24 (LTS)
- C++20 compiler (GCC 9+, Clang 10+, MSVC 2019+)
- CMake 3.18+
- Git
lloyal.node uses git submodules for development:
git clone --recursive https://github.com/lloyal-ai/lloyal.node.git
cd lloyal.node
npm installIf you already cloned without --recursive:
git submodule update --init --recursivenpm run clean
npm install
npm testThis builds:
- llama.cpp + ggml (via cmake-js)
- Native Node.js addon (via cmake-js)
- Runs the test suite
Build with GPU acceleration using the LLOYAL_GPU environment variable:
# CPU only (default on Linux/Windows)
npm run build
# NVIDIA CUDA
LLOYAL_GPU=cuda npm run build
# AMD/Intel Vulkan
LLOYAL_GPU=vulkan npm run build
# Apple Metal (macOS only, auto-enabled)
LLOYAL_GPU=metal npm run buildRequirements:
| Backend | SDK Required |
|---|---|
| CUDA | NVIDIA CUDA Toolkit 12.2+ |
| Vulkan | LunarG Vulkan SDK 1.4.313+ |
| Metal | Xcode Command Line Tools (macOS) |
# Run all tests
npm test
# Clean build and test
npm run clean && npm install && npm testThe models/ directory is not tracked in git (too large). Download test models automatically:
npm run download-modelsThis downloads:
SmolLM2-1.7B-Instruct-Q4_K_M.gguf(1.0GB) - Text generation testsnomic-embed-text-v1.5.Q4_K_M.gguf(80MB) - Embedding tests
Models are cached in CI to avoid re-downloading on every run.
lloyal.node vendors its dependencies (liblloyal and llama.cpp) for npm distribution, since npm doesn't support git submodules.
Step 1: Update Submodules
# Update to latest upstream
git submodule update --remote
# Or update to specific commits
cd liblloyal && git checkout <commit-hash> && cd ..
cd llama.cpp && git checkout <commit-hash> && cd ..
# Commit submodule updates
git add liblloyal llama.cpp
git commit -m "chore: update submodules to latest"Step 2: Vendor the Updates
# Copy submodule sources to vendor/
npm run update-vendors
# Or update specific dependency
npm run update-vendors liblloyal
npm run update-vendors llama.cppThis script:
- Copies files from submodules to
vendor/ - Records commit hashes in
vendor/VERSIONS.json - Creates README in each vendor directory
Step 3: Test with Vendored Sources
# Clean and rebuild to verify vendored sources work
npm run clean
npm install
npm testStep 4: Commit Vendor Updates
git add vendor/
git commit -m "chore: vendor liblloyal and llama.cpp"Step 5: Check for Breaking Changes
cd llama.cpp
git log --oneline <old-commit>..<new-commit>
cd ../liblloyal
git log --oneline <old-commit>..<new-commit>Document any breaking changes in release notes.
Always vendor immediately after updating submodules:
# Update submodules
git submodule update --remote
# Vendor immediately
npm run update-vendors
# Test
npm run clean && npm install && npm test
# Commit together
git add liblloyal llama.cpp vendor/
git commit -m "chore: update dependencies to latest"Before publishing to npm:
# 1. Update submodules to desired versions
git submodule update --remote
# 2. Test with submodules first
npm run clean && npm install && npm test
# 3. Vendor the tested versions
npm run update-vendors
# 4. Test with vendored sources
npm run clean && npm install && npm test
# 5. Update CHANGELOG.md with changes
# 6. Update version in package.jsonReleases are automated via GitHub Actions. To trigger a release:
# Create and push a version tag
git tag v0.2.0
git push origin v0.2.0This triggers the .github/workflows/release.yml workflow which:
- Builds prebuilt binaries for all 13 platforms
- Publishes platform packages to npm (
@lloyal-labs/lloyal.node-*) - Publishes the main package to npm (
lloyal.node)
# Bump version
npm version patch # or minor/major
# Publish to npm
npm publish --access publiclloyal.node/
├── liblloyal/ # Git submodule (dev only)
├── llama.cpp/ # Git submodule (dev only)
├── vendor/ # Vendored copies (committed, published to npm)
│ ├── liblloyal/
│ ├── llama.cpp/
│ └── VERSIONS.json
├── src/ # C++ binding code
├── scripts/ # Build and utility scripts
├── docs/ # User-facing documentation
└── .github/workflows/ # CI/CD pipelines
- C++: Follow liblloyal conventions (see
liblloyal/CONTRIBUTING.md) - TypeScript: Run
npm run lintbefore committing - Commit messages: Use conventional commits (
feat:,fix:,chore:, etc.)
- Fork the repository
- Create a feature branch (
git checkout -b feat/amazing-feature) - Make your changes and test thoroughly
- Commit your changes (
git commit -m 'feat: add amazing feature') - Push to your fork (
git push origin feat/amazing-feature) - Open a Pull Request
- Open an issue on GitHub
- Check existing issues and PRs
- Review the distribution documentation
License: Apache 2.0