This directory contains interactive musical applications built with web standards. Apps range from simple utilities to sophisticated learning tools and creative applications.
The apps section showcases interactive musical tools that serve multiple audiences:
- Musicians & Producers: Utilities for timing, tuning, and production workflows
- Music Students: Learning tools for understanding musical concepts
- Developers: Creative applications demonstrating music-reactive animations and audio processing
Web-First, Standards-Based
- Built with HTML, CSS, and JavaScript (via TypeScript)
- Works directly in browsers without installation
- Responsive design for desktop and mobile
- Accessible and performant
Encapsulated & Portable
- Each app is self-contained and reusable
- Can be extracted to standalone projects or npm packages
- Clean separation between business logic and UI
Cross-Platform Ready
- Web apps are the primary experience
- Optional distribution via iOS App Store and Google Play Store
- Consistent behavior across platforms
- Astro.js: Static site generation with content collections
- Svelte 5: Reactive UI components with modern runes API
- TypeScript: Type-safe development
- Tailwind CSS: Utility-first styling with dark theme
- Vitest: Fast unit testing framework
- astro-icon: Icon system with MDI icon set
- @testing-library/svelte: Component testing utilities
- jsdom: DOM simulation for testing
src/
├── content/
│ └── apps/
│ ├── APPS_README.md (this file)
│ └── bpm-calculator.mdx (app metadata)
├── components/
│ └── apps/
│ └── BpmCalculator.svelte (interactive component)
├── pages/
│ └── apps/
│ ├── index.astro (apps listing page)
│ └── [...slug].astro (individual app pages)
└── utils/
├── bpm.ts (business logic)
└── bpm.test.ts (unit tests)
Each app includes metadata defined in frontmatter:
---
title: "BPM Calculator"
description: "Convert tempo to millisecond durations for musical subdivisions."
component: "BpmCalculator" # Svelte component name
category: "rhythm" # rhythm | learning | creative | utility
keywords:
- "BPM"
- "tempo"
- "timing"
# Optional cross-platform URLs
appStoreUrl: "https://apps.apple.com/..."
playStoreUrl: "https://play.google.com/..."
webUrl: "https://standalone-app.example.com"
---Apps follow a separation of concerns:
-
Business Logic (
src/utils/)- Pure TypeScript functions
- No UI dependencies
- Fully unit tested
- Easily portable to other projects
-
UI Component (
src/components/apps/)- Svelte component for interactivity
- Imports business logic from utils
- Styled with Tailwind CSS
- Uses
client:loaddirective for hydration
-
Content Entry (
src/content/apps/)- Markdown file with metadata
- Explains the app's purpose and usage
- Rendered below the interactive component
Create a utility module in src/utils/:
// src/utils/chord-finder.ts
export function findChords(notes: string[]): Chord[] {
// Pure function logic
}Create tests alongside your utility:
// src/utils/chord-finder.test.ts
import { describe, it, expect } from 'vitest';
import { findChords } from './chord-finder';
describe('findChords', () => {
it('identifies major triads', () => {
expect(findChords(['C', 'E', 'G'])).toEqual([{ name: 'C Major' }]);
});
});Create an interactive component in src/components/apps/:
<!-- src/components/apps/ChordFinder.svelte -->
<script lang="ts">
import { findChords } from '../../utils/chord-finder';
let notes = $state(['C', 'E', 'G']);
let chords = $derived(findChords(notes));
</script>
<div class="chord-finder">
<!-- UI implementation -->
</div>
<style>
/* Tailwind-first, scoped CSS only for unique needs */
</style>Add metadata and documentation with component import:
<!-- src/content/apps/chord-finder.mdx -->
---
title: "Chord Finder"
description: "Identify chords from selected notes"
component: "ChordFinder"
category: "learning"
keywords: ["chords", "harmony", "music theory"]
---
import ChordFinder from '../../components/apps/ChordFinder.svelte';
# Chord Finder
<ChordFinder client:load />
Select notes on the keyboard to discover what chords they form...Note: Using MDX (.mdx extension) allows importing and rendering Svelte components directly in the content. The component is embedded right where you want it to appear in the page layout.
# Run unit tests
npm test
# Start dev server
npm run dev
# Navigate to /apps/chord-finder
# Verify app works as expected
# Build for production
npm run buildAll business logic must be unit tested:
- Test pure functions in isolation
- Cover edge cases and error conditions
- Aim for high code coverage
- Fast execution (< 1ms per test)
Complex UI interactions can be tested with @testing-library/svelte:
- Test user interactions (clicks, input)
- Verify reactive state updates
- Check accessibility (ARIA labels, keyboard nav)
- App renders correctly on desktop
- App works on mobile viewport
- Dark theme styling is consistent
- Animations are smooth (60fps)
- Inputs validate appropriately
- Keyboard navigation works
- Screen reader announces changes
Apps are designed for easy extraction:
# Create new package
mkdir bpm-calculator
cd bpm-calculator
npm init
# Copy files
cp src/utils/bpm.ts .
cp src/components/apps/BpmCalculator.svelte .
# Add dependencies
npm install svelte
npm install -D typescript vitest
# Publish
npm publish# Create Vite + Svelte project
npm create vite@latest bpm-calculator-app -- --template svelte-ts
# Copy component and utilities
cp src/components/apps/BpmCalculator.svelte src/
cp src/utils/bpm.ts src/
# Deploy to Vercel/Netlify/Cloudflare PagesUse frameworks like:
- Capacitor: Web app to iOS/Android
- Tauri: Web app to native desktop
- Expo: React Native (requires porting from Svelte)
- BPM Calculator: Converts tempo to millisecond values for musical subdivisions
- Category: Rhythm
- Features: Real-time calculation, dotted/triplet variations
- Use cases: Audio production, delay timing, animation sync
- PianoFitness: Gamified piano learning and practice tool
- Music-Reactive Animations: Creative toolkit for visualizing audio
- Scale Explorer: Interactive scale and mode reference
- Metronome: Customizable rhythm practice tool
When adding apps:
- Keep it focused: Each app should do one thing well
- Test thoroughly: Business logic must have unit tests
- Document clearly: Explain use cases and features in markdown
- Style consistently: Follow Tailwind conventions and dark theme
- Consider accessibility: ARIA labels, keyboard nav, screen readers
- Think portable: Could this be useful as a standalone package?
- Astro Content Collections
- Svelte 5 Documentation
- Vitest Documentation
- Tailwind CSS
- Web Audio API (for audio-processing apps)