A client-side web application that allows you to download all attachments from your Airtable tables in a single ZIP file. Built with React, TypeScript, and Shadcn/ui.
- 🔐 Secure Authentication: Uses Airtable Personal Access Tokens (stored locally only)
- 📦 Batch Download: Download all attachments from selected tables in one ZIP file
- 🔍 Filtering: Apply Airtable formula filters to download specific records
- 📊 Preview: See how many files will be downloaded before starting
- 🎨 Clean UI: Built with Shadcn/ui components for a modern, accessible interface
- 🔒 Privacy First: All processing happens client-side - no data is sent to our servers
- 💾 Smart Naming: Optionally use field values as filenames
- Authenticate: Enter your Airtable Personal Access Token
- Select Base: Choose the Airtable base you want to work with
- Select Table: Pick the table containing your attachments
- Choose Field: Select the attachment field you want to download
- Optional Settings:
- Choose a filename field to name downloaded files
- Add a filter formula to download only specific records
- Preview: See how many files will be downloaded
- Download: Click the download button to get all attachments as a ZIP file
This application runs entirely client-side.
- ✅ No data is sent to our servers
- ✅ No data is stored on our servers
- ✅ Your Airtable token is stored only in your browser's localStorage
- ✅ When you close the page, all data is deleted
- ✅ All processing happens in your browser
- Node.js 18+ and npm
- An Airtable account with Personal Access Token
- Clone the repository:
git clone <repository-url>
cd batch-file-downloader- Install dependencies:
npm install- Start the development server:
npm run dev- Open your browser to
http://localhost:5173
npm run buildThe built files will be in the dist directory.
- Go to Airtable Account Settings
- Navigate to "Developer" → "Personal access tokens"
- Click "Create new token"
- Give it a name and select the scopes:
data.records:read- Required to read recordsschema.bases:read- Required to list bases and tables
- Copy the token and use it in the app
- Enter your Personal Access Token when prompted
- Select your base, table, and attachment field
- Click "Download All Attachments"
You can filter records using Airtable formula syntax:
{Status} = "Active"- Download only active records{Created} > "2024-01-01"- Download records created after a dateAND({Status} = "Active", {Priority} = "High")- Multiple conditions
If you select a filename field, downloaded files will be named using that field's value. For example:
- If the filename field contains "Invoice-2024", files will be named
Invoice-2024_1.pdf,Invoice-2024_2.pdf, etc. - If no filename field is selected, files will be named using the record ID
- React 19 - UI framework
- TypeScript - Type safety
- Vite - Build tool and dev server
- Tailwind CSS - Styling
- Shadcn/ui - UI components
- JSZip - ZIP file creation
- File-saver - File downloads
- Airtable REST API - Data fetching
- Client-Side Only: No backend server required
- Component-Based: Modular React components
- Type-Safe: Full TypeScript coverage
- Responsive: Works on desktop and mobile devices
The app uses the Airtable REST API:
GET /meta/bases- List all basesGET /meta/bases/{baseId}/tables- List tables in a baseGET /meta/bases/{baseId}/tables/{tableId}- Get table schemaGET /{baseId}/{tableId}- Fetch records (with optional filter)
- CORS: Some browsers may block direct API calls. If you encounter CORS issues, you may need to use a browser extension or configure CORS on your Airtable base.
- Rate Limits: Airtable API has rate limits. For large datasets, downloads may take time.
- Browser Memory: Very large downloads (thousands of files) may cause browser memory issues.
Contributions are welcome! Please feel free to submit a Pull Request.
- Fork the repository
- Create your feature branch (
git checkout -b feature/amazing-feature) - Commit your changes (
git commit -m 'Add some amazing feature') - Push to the branch (
git push origin feature/amazing-feature) - Open a Pull Request
This project is open source and available under the MIT License.
For issues, questions, or contributions, please open an issue on GitHub.
Built with ❤️ by useefficiently
Note: This is an open source product by useefficiently. We don't store any of your data. Everything runs in your browser.