@quasarbright/projection
v1.0.3
Published
A static site generator that creates a beautiful, interactive gallery to showcase your coding projects. Features search, filtering, tags, responsive design, and an admin UI.
Maintainers
Readme
Projection
A modern, reusable static site generator that creates beautiful, interactive galleries to showcase your coding projects. Generate your portfolio site with a single command.
Here is an example of a portfolio site using Projection: https://quasarbright.github.io/portfolio/
And its source code: https://github.com/quasarbright/portfolio

✨ Features
- 🖥️ Web Admin Interface - Manage projects through an intuitive web UI with live preview
- 📦 Easy Installation - Install globally from source
- 🚀 Quick Setup - Initialize a new project in seconds
- 📱 Responsive Design - Works on desktop, tablet, and mobile
- 🔍 Search & Filter - Real-time search and tag-based filtering
- ⭐ Featured Projects - Highlight your best work
- 🏷️ Flexible Tagging - Organize projects with tags (ANY/ALL filtering)
- 🔥 Hot Reloading - Development server with automatic rebuild and refresh
- 🎨 Customizable - Override default styles and scripts
- 🚢 GitHub Pages Deployment - Deploy with a single command (or through the admin UI)
📋 Table of Contents
- Installation
- Quick Start
- Admin Interface
- Configuration
- Project Data Format
- Customization
- Troubleshooting
- Deployment
- Project Structure
- Contributing
- License
- Links
📦 Installation
Requirements
- Node.js 14.0.0 or higher
Install from npm
npm install -g @quasarbright/projectionInstall from Source
# Clone the repository
git clone https://github.com/quasarbright/projection.git
cd projection
# Install dependencies
npm install
# Build the project
npm run build
# Link globally (makes 'projection' command available)
npm linkNow you can use the projection command from anywhere on your system!
🚀 Quick Start
1. Initialize a New Project
# Create a new directory for your portfolio
mkdir my-portfolio
cd my-portfolio
# Initialize with sample files
projection initThis creates:
projects.yaml- Sample project dataprojection.config.json- Configuration file with defaults.gitignore- Git ignore patternsREADME.md- Quick start guide
2. Edit Your Projects
Option A: Use the Admin Interface (Recommended)
projection adminOpens a web-based editor at http://localhost:3000 where you can:
- Add, edit, and delete projects visually
- Upload project thumbnails
- See live preview of your portfolio
- Manage tags with autocomplete
Option B: Edit Files Directly
Edit projects.yaml to add your own projects:
projects:
- id: "my-awesome-project"
title: "My Awesome Project"
description: "A brief description of what this project does"
creationDate: "2024-01-15"
tags: ["web", "javascript"]
pageLink: "https://example.com/my-project"
sourceLink: "https://github.com/username/my-project"
thumbnailLink: "./screenshots/project.png"
featured: true3. Start Development Server
projection devThis will:
- Build your site
- Start a local server at http://localhost:8080
- Watch for changes and auto-reload
- Open your browser automatically
4. Build for Production
projection buildYour site will be generated in the dist/ directory, ready for deployment.
🖥️ Admin Interface
Projection includes a powerful web-based admin interface that makes managing your portfolio easier than editing files directly.
Starting the Admin Interface
projection adminThis opens a local web server at http://localhost:3000 with a full-featured admin UI.
Features
Visual Project Editor
- Create, edit, and delete projects through an intuitive form interface
- Live preview of your portfolio as you make changes
- Real-time validation with helpful error messages
Image Management
- Upload project thumbnails directly through the UI
- Drag-and-drop image upload
- Automatic image optimization and storage
Tag Management
- Visual tag selector with autocomplete
- See tag usage counts across all projects
- Create new tags on the fly
Live Preview
- See your changes instantly in an embedded preview
- Click projects in the preview to edit them
- Test search and filtering in real-time
Smart Editing
- Form validation ensures data integrity
- Automatic ID generation from project titles
- Date picker for creation dates
- Toggle featured status with a checkbox
⚙️ Configuration
Configuration File
Projection uses a projection.config.json file for site configuration. This file is separate from your project data and can be edited through the admin interface or manually.
Configuration is loaded in this order:
- Command-line
--configoption projection.config.jsonin current directory- Default configuration
projection.config.json
JSON format configuration file:
{
"title": "My Projects",
"description": "A showcase of my coding projects",
"baseUrl": "./",
"dynamicBackgrounds": [],
"customStyles": null,
"customScripts": null,
"output": "dist"
}Configuration Options
| Option | Type | Default | Description |
|--------|------|---------|-------------|
| title | string | "My Projects" | Site title displayed in header |
| description | string | "A showcase of my coding projects" | Site description and meta description |
| baseUrl | string | "./" | Base URL for resolving relative paths |
| dynamicBackgrounds | string[] | [] | Array of background URLs (see Dynamic Backgrounds) |
| customStyles | string | null | Path to custom styles directory |
| customScripts | string | null | Path to custom scripts directory |
| output | string | "dist" | Output directory path |
Editing Configuration
Option A: Admin Interface (Recommended)
Use the Settings button in the admin interface to edit configuration through a user-friendly form with validation.
Option B: Edit Manually
Edit projection.config.json directly in your text editor.
Path Resolution
The baseUrl is used to resolve relative paths in your project data:
- Relative paths (
./path,../path,filename) → Resolved relative tobaseUrl - Absolute paths (
/path) → Used as-is - Full URLs (
https://...) → Used as-is
Example:
// Config
baseUrl: "https://username.github.io/"
// Project data
pageLink: "./my-project/" // → https://username.github.io/my-project/
pageLink: "/absolute" // → /absolute
pageLink: "https://..." // → https://...🎨 Dynamic Backgrounds
Projection supports dynamic backgrounds that add visual interest to your portfolio. These are web pages (like p5.js sketches, animations, or visualizations) that display behind your project cards.
What are Dynamic Backgrounds?
Dynamic backgrounds are full-screen web pages loaded in an iframe behind your portfolio content. Each time a visitor loads your site, one background is randomly selected from your list, creating a unique experience.
Managing Dynamic Backgrounds
Option A: Admin Interface (Recommended)
- Open the admin interface:
projection admin - Click the Settings button
- Navigate to the Dynamic Backgrounds tab
- Add background URLs with live preview
- Test each background before saving
The admin interface provides:
- Live iframe previews of each background
- Visual status indicators (loaded/error)
- Click to expand and test backgrounds full-screen
Option B: Edit Configuration Manually
Add background URLs to your projection.config.json:
{
"title": "My Projects",
"description": "My portfolio",
"baseUrl": "./",
"dynamicBackgrounds": [
"https://example.com/background1",
"https://example.com/background2",
"https://example.com/background3"
]
}Background Requirements
Your background pages should:
- Be full-screen - Fill the entire viewport
- Work in an iframe - Not blocked by X-Frame-Options
- Be performant - Lightweight animations that don't slow down the site
Best Practices
- Test performance - Ensure backgrounds don't slow down your site
- Keep it subtle - Backgrounds should enhance, not distract from your projects
- Consider accessibility - Avoid flashing or rapidly moving elements
- Mobile-friendly - Test on mobile devices for performance
📊 Project Data Format
Supported Formats
Projection automatically detects and reads project data from:
projects.yaml(recommended)projects.ymlprojects.json
YAML Format (Recommended)
projects:
- id: "awesome-project"
title: "Awesome Project"
description: "This project does amazing things with modern web technologies"
creationDate: "2024-01-15"
tags: ["web", "javascript", "typescript"]
pageLink: "./awesome-project/"
sourceLink: "https://github.com/username/awesome-project"
thumbnailLink: "./screenshots/awesome.png"
featured: true
- id: "another-project"
title: "Another Project"
description: "A different project with different features"
creationDate: "2024-02-20"
tags: ["python", "data-science"]
pageLink: "https://example.com/another-project"
thumbnailLink: "./screenshots/another.png"JSON Format
{
"projects": [
{
"id": "awesome-project",
"title": "Awesome Project",
"description": "This project does amazing things",
"creationDate": "2024-01-15",
"tags": ["web", "javascript"],
"pageLink": "./awesome-project/",
"sourceLink": "https://github.com/username/awesome-project",
"thumbnailLink": "./screenshots/awesome.png",
"featured": true
}
]
}Project Fields
| Field | Type | Required | Description |
|-------|------|----------|-------------|
| id | string | ✅ Yes | Unique identifier (must be valid URL slug: lowercase, alphanumeric, hyphens only) |
| title | string | ✅ Yes | Display name of the project |
| description | string | ✅ Yes | Project description (truncated with ellipsis on cards) |
| creationDate | string | ✅ Yes | ISO date string (YYYY-MM-DD format) |
| tags | string[] | ✅ Yes | Array of tags for categorization and filtering |
| pageLink | string | ✅ Yes | Primary link to the project (page, demo, or live site) |
| sourceLink | string | ❌ No | Link to source code repository (shows "Source Code" button) |
| thumbnailLink | string | ❌ No | Path or URL to project screenshot (used as card background) |
| featured | boolean | ❌ No | Highlight the project with special styling (border and badge) |
Field Validation Rules
Project ID (id)
- Must be unique across all projects
- Must be a valid URL slug:
- Lowercase letters only
- Can contain numbers and hyphens
- Cannot start or end with a hyphen
- Pattern:
/^[a-z0-9]+(?:-[a-z0-9]+)*$/
Valid IDs:
id: "my-project"
id: "project-123"
id: "awesome-web-app"Invalid IDs:
id: "My-Project" # ❌ Contains uppercase
id: "-my-project" # ❌ Starts with hyphen
id: "my_project" # ❌ Contains underscore
id: "my project" # ❌ Contains spaceCreation Date (creationDate)
- Must be in ISO date format:
YYYY-MM-DD - Used for sorting projects by date
Valid dates:
creationDate: "2024-01-15"
creationDate: "2023-12-31"Invalid dates:
creationDate: "01/15/2024" # ❌ Wrong format
creationDate: "2024-1-5" # ❌ Missing leading zeros🎨 Customization
Custom Styles
You can override the default styles by creating a styles/ directory in your project:
mkdir styles
# Add your custom CSS filesDirectory structure:
my-portfolio/
├── styles/
│ ├── main.css # Override main styles
│ ├── cards.css # Override card styles
│ └── custom.css # Add your own styles
├── projects.yaml
└── projection.config.jsonIf the styles/ directory exists, Projection will use your custom styles instead of the bundled defaults. You can copy the default styles and modify them:
Default styles included:
main.css- Layout, theme, components, dark color schemecards.css- Project card styling, 3D hover effects, background imagesmodal.css- Modal styling (for future use)
Custom Scripts
Similarly, you can override JavaScript functionality:
mkdir scripts
# Add your custom JavaScript filesDefault scripts included:
search.js- Real-time search functionalityfilter.js- Tag filtering and sortingmodal.js- Modal functionality (for future use)dynamic-background.js- Dynamic background effects
Custom Assets
Place additional assets in an assets/ directory:
mkdir assets
# Add favicon, images, etc.Template Resolution
Projection uses this priority for templates:
- User custom files in your project directory (
styles/,scripts/,assets/) - Bundled defaults from the package
This allows you to:
- Use defaults out of the box
- Override specific files as needed
- Mix custom and default files
🔧 Troubleshooting
Build Fails with "Projects file not found"
Problem: Projection can't find your project data file.
Solution:
# Make sure you have one of these files:
ls projects.yaml # or projects.yml or projects.json
# If not, initialize a new project:
projection initInvalid Project ID Error
Problem: Project ID doesn't match the required format.
Solution: Project IDs must be valid URL slugs:
# ✅ Good
id: "my-awesome-project"
id: "project-123"
# ❌ Bad
id: "My Project" # Use: "my-project"
id: "project_name" # Use: "project-name"
id: "-my-project" # Use: "my-project"Dev Server Port Already in Use
Problem: Port 8080 is already in use.
Solution:
# Use a different port
projection dev --port 3000Changes Not Reflecting in Browser
Problem: Browser shows old content after changes.
Solution:
- Make sure dev server is running (
projection dev) - Check console for rebuild messages
- Hard refresh browser (Ctrl+Shift+R or Cmd+Shift+R)
- Clear browser cache
Missing Thumbnails
Problem: Project thumbnails not showing.
Solution:
- Check that
thumbnailLinkpaths are correct - Verify images exist at specified paths
- Run
projection devand use inspect element to check the img src on the card. You may need to updatethumbnailLinkorbaseUrl.
Build Output Directory Not Created
Problem: dist/ directory doesn't exist after build.
Solution:
# Check for build errors
projection build
# Try cleaning first
projection build --clean
# Check file permissions
ls -la🚢 Deployment
The generated dist/ directory contains everything needed for deployment.
Deploying to GitHub Pages
Projection includes a built-in deploy command that makes deploying to GitHub Pages effortless. It automatically builds your site and publishes it to the gh-pages branch.
Quick Start
# Deploy your site in one command
projection deployThat's it! Your site will be built and deployed to GitHub Pages automatically.
Prerequisites
Before deploying, make sure you have:
- Git installed on your system
- A Git repository initialized in your project:
git init git add . git commit -m "Initial commit" - A remote repository configured (usually on GitHub):
git remote add origin https://github.com/username/repository-name.git
Step-by-Step Deployment
1. Configure your site for GitHub Pages
Add a baseUrl to your projection.config.json:
{
"title": "My Portfolio",
"description": "My awesome projects",
"baseUrl": "/"
}Note: The
baseUrlis important for GitHub Pages if you're linking to other repos' pages.
2. Deploy your site
projection deployThis command will:
- ✅ Validate your Git setup
- ✅ Build your site with the correct base URL
- ✅ Create/update the
gh-pagesbranch - ✅ Push your site to GitHub
- ✅ Display your GitHub Pages URL
3. Enable GitHub Pages (first time only)
After your first deployment:
- Go to your repository on GitHub
- Click Settings → Pages
- Under Source, select:
- Branch:
gh-pages - Folder:
/ (root)
- Branch:
- Click Save
Your site will be live at https://username.github.io/repository-name/ within a few minutes!
Configuration Options
In projection.config.json
{
"baseUrl": "/repository-name/",
"homepage": "portfolio.example.com",
"deployBranch": "gh-pages"
}Configuration notes:
baseUrl- Required for GitHub Pages (use your repository name)homepage- Optional: Custom domain (creates CNAME file)deployBranch- Optional: Custom deployment branch (defaults to "gh-pages")
Command-Line Options
# Deploy to a custom branch
projection deploy --branch main
# Custom commit message
projection deploy --message "Update portfolio with new projects"
# Use a different Git remote
projection deploy --remote upstream
# Skip the build step (use existing dist/)
projection deploy --no-build
# Deploy from a custom directory
projection deploy --dir build
# Simulate deployment without pushing
projection deploy --dry-run
# Force push (overwrites remote history)
projection deploy --forceExamples for Different Repository Types
Example 1: Project Repository (most common)
Repository: https://github.com/username/my-portfolio
Configuration:
{
"title": "My Portfolio",
"baseUrl": "/my-portfolio/"
}Deploy:
projection deployResult: Site live at https://username.github.io/my-portfolio/
Example 2: Custom Domain
Repository: https://github.com/username/portfolio
Configuration:
{
"title": "My Portfolio",
"baseUrl": "/",
"homepage": "portfolio.example.com"
}Notes:
- Use
baseUrl: "/"for custom domains (root path) - The
homepagefield creates a CNAME file for your custom domain
Deploy:
projection deployDNS Setup (required for custom domains):
- Add a CNAME record pointing to
username.github.io - Or add A records pointing to GitHub's IPs:
185.199.108.153185.199.109.153185.199.110.153185.199.111.153
Result: Site live at https://portfolio.example.com/
Troubleshooting Deployment
"Git is not installed"
Problem: Git is not found on your system.
Solution:
# Install Git
# macOS (with Homebrew):
brew install git
# Windows: Download from https://git-scm.com/
# Linux (Ubuntu/Debian):
sudo apt-get install git"Not a git repository"
Problem: Your project is not a Git repository.
Solution:
# Initialize Git repository
git init
git add .
git commit -m "Initial commit""No git remote found"
Problem: No remote repository is configured.
Solution:
# Add a remote (replace with your repository URL)
git remote add origin https://github.com/username/repository-name.git
# Verify remote was added
git remote -v"Authentication failed"
Problem: Git cannot authenticate with GitHub.
Solution:
https://docs.github.com/en/authentication/keeping-your-account-and-data-secure/about-authentication-to-github#authenticating-with-the-command-line
"Site not updating after deployment"
Problem: GitHub Pages shows old content after deployment.
Solution:
- Wait a few minutes - GitHub Pages can take 1-10 minutes to update
- Check GitHub Actions - Go to your repository → Actions tab to see build status
- Hard refresh browser - Press Ctrl+Shift+R (or Cmd+Shift+R on Mac)
- Verify gh-pages branch - Check that the branch has your latest changes
- Check GitHub Pages settings - Ensure it's configured to use the
gh-pagesbranch
"404 errors for assets (CSS, images)"
Problem: Your site loads but CSS and images are broken.
Solution: Check your baseUrl configuration:
- Make sure it has a trailing slash
- inspect the project's card, find the
imgfor the thumbnail, and look at itssrcattribute. Make sure it is correct. You may need to adjustbaseurl.
"Custom domain not working"
Problem: Custom domain shows 404 or doesn't resolve.
Solution:
Verify CNAME file exists:
# Check gh-pages branch for CNAME file git checkout gh-pages cat CNAME # Should contain your domain git checkout mainCheck DNS configuration:
- CNAME record should point to
username.github.io - DNS changes can take up to 48 hours to propagate
- Use
dig portfolio.example.comto verify DNS
- CNAME record should point to
Configure in GitHub:
- Go to Settings → Pages
- Enter your custom domain
- Enable "Enforce HTTPS" (after DNS propagates)
Update your config:
{ baseUrl: "/", homepage: "portfolio.example.com", };
"Build fails during deployment"
Problem: The build step fails before deployment.
Solution:
# Test build locally first
projection build
# Check for errors in your projects.yaml
# Common issues:
# - Invalid project IDs
# - Missing required fields
# - Invalid date formats
# If build works locally, try:
projection deploy --clean📁 Project Structure
my-portfolio/
├── projects.yaml # Your project data
├── projection.config.json # Configuration (optional)
├── styles/ # Custom styles (optional)
│ ├── main.css
│ └── custom.css
├── scripts/ # Custom scripts (optional)
│ └── custom.js
├── assets/ # Static assets (optional)
│ └── favicon.ico
├── screenshots/ # Project thumbnails
│ ├── project1.png
│ └── project2.png
└── dist/ # Generated site (created by build)
├── index.html
├── styles/
├── scripts/
└── assets/🤝 Contributing
Contributions are welcome! Here's how you can help:
- Report bugs - Open an issue with details and reproduction steps
- Suggest features - Share your ideas for improvements
- Submit pull requests - Fix bugs or add features
Development Setup
# Clone the repository
git clone https://github.com/quasarbright/projection.git
cd projection
# Install dependencies
npm install
# Build the project
npm run build
# Run tests
npm test
# Make projection command accessible
npm linkCreating a test portfolio
cd ../
mkdir projection-test
cd projection-test
projection init
projection adminRunning Tests
# Run all tests
npm test
# Run tests in watch mode
npm run test:watch
# Run specific test file
npm test -- config.test.ts📄 License
MIT License - see LICENSE file for details.
🔗 Links
- GitHub Repository: https://github.com/quasarbright/projection
- Live Demo: https://quasarbright.github.io/portfolio/
- Author: Mike Delmonaco
- Issues: https://github.com/quasarbright/projection/issues
Need help? Open an issue on GitHub or check the troubleshooting section.
