An open-source alternative frontend to Ultimate Guitar, built with Next.js.
- ๐ธ Search guitar tabs and chords from Ultimate Guitar
- ๐จ Clean, ad-free interface with no popups or distractions
- ๐ Auto-scroll for hands-free reading while playing
- ๐ต Transpose chords to any key (-11 to +11 semitones)
- โญ Save favorites locally (no account needed) or to the cloud (sign in)
- ๐ Setlists โ create and manage song setlists (requires account)
- ๐ Dark mode support with system preference detection
- ๐จ๏ธ Print-friendly formatting
- ๐ฏ Chord diagrams with fingering positions
- ๐ฑ Responsive design works on mobile and desktop
- ๐ ChordPro format support - view, export, and copy in standard ChordPro notation
- ๐ฒ Progressive Web App (PWA) - Install on mobile/desktop for offline access and app-like experience
- Framework: Next.js 14 (App Router)
- Language: TypeScript
- UI: React 18, Tailwind CSS, DaisyUI
- Data Fetching: Axios, Cheerio (web scraping)
- Database: Airtable
- Authentication: NextAuth.js v4 (email + password)
- Deployment: Vercel/Node.js
- Node.js 22.0.0 or higher
- npm
- Clone the repository and install dependencies:
cd freetar-nextjs
npm install- Copy the example environment file and fill in your values:
cp .env.example .env.local # or create .env.local manually- Run the development server:
npm run dev- Open http://localhost:3000 in your browser.
The app works without any configuration for anonymous users (search, view tabs, localStorage favorites). To enable cloud sync and setlists, complete the Airtable setup below.
Go to airtable.com and create a new base. Then create these 5 tables with the exact names and field types shown:
Table: Users
| Field | Type |
|---|---|
| Single line text (primary field โ rename the default "Name" field) | |
| PasswordHash | Single line text |
| CreatedAt | Single line text |
Table: Tabs
| Field | Type |
|---|---|
| TabUrl | Single line text (primary field) |
| ArtistName | Single line text |
| SongName | Single line text |
| Type | Single line text |
| Version | Number |
| Votes | Number |
| Rating | Number |
| Difficulty | Single line text |
| Tuning | Single line text |
| Capo | Number |
| TabContent | Long text |
| Chords | Long text |
| FingersForStrings | Long text |
| Alternatives | Long text |
| CreatedAt | Single line text |
Table: Favorites
| Field | Type |
|---|---|
| UserId | Single line text (primary field) |
| TabId | Single line text |
| CreatedAt | Single line text |
Table: Setlists
| Field | Type |
|---|---|
| UserId | Single line text (primary field) |
| Name | Single line text |
| Description | Long text |
| ShareToken | Single line text |
| CreatedAt | Single line text |
| UpdatedAt | Single line text |
Table: SetlistItems
| Field | Type |
|---|---|
| SetlistId | Single line text (primary field) |
| TabId | Single line text |
| Position | Number |
| Notes | Long text |
| Transpose | Number |
| Capo | Number |
| CreatedAt | Single line text |
Note: Use Single line text (not "Link to another record") for all ID fields. Table and field names are case-sensitive.
- API Key: airtable.com/account โ Personal Access Tokens โ Create token
- Scopes needed:
data.records:read,data.records:write
- Scopes needed:
- Base ID: Open your base in Airtable โ Help โ API documentation โ the Base ID starts with
app
Add to .env.local:
AIRTABLE_API_KEY=pat...
AIRTABLE_BASE_ID=app...
NEXTAUTH_SECRET=<run: openssl rand -base64 32>
NEXTAUTH_URL=http://localhost:3000
NEXT_PUBLIC_NEXTAUTH_ENABLED=trueUsers are added directly in the Airtable Users table. Generate a bcrypt hash for their password:
node -e "require('bcryptjs').hash('their-password', 12).then(console.log)"Then create a record with their Email and the generated hash as PasswordHash.
freetar-nextjs/
โโโ src/
โ โโโ app/ # Next.js App Router pages
โ โ โโโ api/ # API routes
โ โ โ โโโ search/ # Search API endpoint
โ โ โ โโโ tab/ # Tab data API endpoint
โ โ โโโ search/ # Search results page
โ โ โโโ tab/ # Tab display page
โ โ โโโ about/ # About page
โ โ โโโ layout.tsx # Root layout
โ โ โโโ page.tsx # Home page (favorites)
โ โ โโโ globals.css # Global styles
โ โโโ components/ # React components
โ โ โโโ Navbar.tsx # Navigation bar with search
โ โ โโโ SearchResults.tsx # Search results table
โ โ โโโ TabDisplay.tsx # Tab display with controls
โ โ โโโ ChordDiagram.tsx # Chord fingering visualization
โ โโโ lib/ # Utility libraries
โ โ โโโ ug.ts # Ultimate Guitar scraping logic
โ โโโ types/ # TypeScript type definitions
โ โโโ index.ts # Shared types
โโโ public/ # Static assets
โ โโโ guitar.png # Logo/favicon source
โ โโโ manifest.json # PWA manifest file
โ โโโ icon-*.png # PWA icons (8 sizes)
โ โโโ sw.js # Service worker (generated)
โโโ package.json # Dependencies and scripts
โโโ tsconfig.json # TypeScript configuration
โโโ next.config.js # Next.js configuration
โโโ README.md # This file
- Enter a song name or artist in the search bar
- Click the search button or press Enter
- Browse results and click on a tab to view it
- Auto-scroll: Toggle the autoscroll switch and adjust speed with โฎโฎ and โฏโฏ
- Transpose: Use โ and โ to change the key, click the displayed value to reset
- Show chords: Toggle chord diagrams with fingering positions
- Favorites: Click the โ to save/remove from favorites
- ChordPro View: Switch between HTML and ChordPro format display
- Export: Download tabs as
.chofiles or copy to clipboard
See CHORDPRO.md for detailed ChordPro documentation.
- View all favorites on the home page
- Export favorites to JSON file for backup
- Import favorites from JSON file
- Click the ๐ icon to toggle dark/light mode
- Respects system preference by default
- Preference saved in browser localStorage
Freetar can be installed as a standalone app on your device:
Mobile (Android/iOS):
- Visit the site in your mobile browser
- Look for the "Add to Home Screen" prompt or option in the browser menu
- Tap "Add" or "Install" to install the app
- Launch from your home screen like a native app
Desktop (Chrome/Edge):
- Visit the site in Chrome or Edge
- Look for the install icon (โ) in the address bar
- Click it and confirm to install
- Access from your applications menu or taskbar
PWA Benefits:
- Works offline - Access your favorites and previously viewed tabs without internet
- Faster loading - Cached resources load instantly
- Native app experience - No browser UI, full screen mode
- Auto-updates - Service worker updates automatically with new versions
npm run build
npm startOr deploy to Vercel:
vercelFreetar respects your privacy:
- Anonymous users: all favorites stored locally in your browser (localStorage)
- Authenticated users: favorites and setlists stored in your own Airtable base
- No analytics or tracking of any kind
- Searches and tab requests are proxied through the Next.js API routes (no browser CORS)
- All chord and tab data is provided by Ultimate Guitar
- This project is not affiliated with Ultimate Guitar
- Original Python version: freetar
GPL 3.0 - See LICENSE file for details
Contributions are welcome! Please feel free to submit a Pull Request.
If you encounter any issues, please open an issue on GitHub.