Run jsPsych experiments on tablets without internet. Data is stored locally and can be exported when you're ready.
- Go to github.com/new
- Name it
my-experiment
(or whatever you want) - Make it Public
- Don't add README, .gitignore, or license
- Click Create repository
git clone https://github.com/YOUR_USERNAME/my-experiment.git
cd my-experiment
npx @jspsych/new-pwa
You'll be prompted for:
- Experiment title: A human-readable title (default: folder name)
- Template: Choose one:
- CDN imports - Simpler, no build step, easier to modify (recommended)
- npm packages - TypeScript, build step, type checking
If you chose CDN template:
npm run dev
If you chose Build template:
npm install
npm run dev
Open http://localhost:5173 in your browser.
git add .
git commit -m "Initial commit"
git push
Then enable GitHub Pages:
- Go to your repository on GitHub
- Settings → Pages
- Under "Source", select GitHub Actions
- Wait ~1 minute
Your experiment is now live at: https://YOUR_USERNAME.github.io/my-experiment/
To update later:
git add .
git commit -m "Update experiment"
git push
GitHub automatically rebuilds and deploys.
Tablets need internet for first install only. After that, everything works offline.
- Open Safari (must be Safari, not Chrome)
- Navigate to your deployed URL (e.g.,
https://username.github.io/my-experiment/
) - Tap the Share button (square with arrow up)
- Scroll down and tap "Add to Home Screen"
- Tap "Add"
- App icon appears on home screen
- Open Chrome
- Navigate to your deployed URL
- Tap the ⋮ menu button
- Tap "Add to Home Screen" or "Install app"
- Tap "Install"
- App icon appears on home screen
Test offline mode: Enable airplane mode and open the app. It should work!
Participants run the experiment. Data is automatically saved to the device's local storage (IndexedDB) after each trial.
-
Open the installed app
-
Navigate to
/admin
:- Tap the address bar
- Current URL:
https://username.github.io/my-experiment/
- Change to:
https://username.github.io/my-experiment/admin
- Press Go
-
You'll see the Data Manager with:
- Number of completed sessions
- Storage usage
- List of all sessions
-
Tap "Export All" button
-
Choose format:
- CSV - One file per session (downloads as ZIP if multiple sessions)
- JSON - All sessions in one structured file
- ZIP - All sessions as CSVs in a ZIP file
-
File downloads to tablet
iOS:
- Email the file to yourself
- AirDrop to a Mac
- Upload to iCloud Drive, Dropbox, etc.
- Connect to Mac with cable and use Finder
Android:
- Email the file to yourself
- Upload to Google Drive, Dropbox, etc.
- Connect to computer with USB cable
Alternative: Email directly from data manager (if you add email functionality to admin.js)
The included GitHub Actions workflow deploys your experiment automatically. Configuration is in .github/workflows/deploy.yml
.
For Build template, the base URL is automatically detected from your GitHub repository name. If deploying to a custom domain, edit vite.config.js
:
export default defineConfig({
base: "/", // Change from auto-detect to root path for custom domains
// ...
});
For CDN template, no configuration needed for GitHub Pages.
Edit public/manifest.json
to customize how your app appears when installed:
{
"name": "My Experiment",
"short_name": "Experiment",
"description": "Description shown during install",
"icons": [
{
"src": "/icon-192.png",
"sizes": "192x192",
"type": "image/png"
}
]
}
Replace icons in public/
with your own (use jsPsych logo or custom icons).
Configure storage behavior when initializing jsPsych:
const jsPsych = await initJsPsychOffline({
offline: {
dbName: "my-experiment", // Custom database name
typicalSessionSize: 2 * 1024 * 1024, // 2MB - affects low storage warnings
sessionMetadata: {
// Custom metadata per session
experimentVersion: "1.0.0",
condition: "control",
},
},
});
PWA won't install:
- Verify you're using HTTPS (GitHub Pages provides this automatically)
- On iOS, must use Safari browser
- Try refreshing the page once before installing
Data not saving:
- Check browser console for errors
- Verify you're using
initJsPsychOffline()
notinitJsPsych()
- Make sure private browsing is OFF
Can't access admin page:
- Installed PWAs may cache old URLs
- Type the full URL manually:
https://yoursite.com/admin.html
- Or uninstall and reinstall the PWA
Deployment not working:
- Check GitHub Actions tab for errors
- Verify GitHub Pages source is set to "GitHub Actions"
- For Build template, ensure
package.json
andpackage-lock.json
are committed
- Getting Started Guide - Detailed walkthrough
- API Reference - Complete API documentation
- Deployment Guide - Advanced deployment options
This monorepo contains two npm packages:
- @jspsych/offline-storage - Runtime library for offline data persistence
- @jspsych/new-pwa - CLI tool for creating new experiments
Contributing to this project:
# Install dependencies
npm install
# Build all packages
npm run build
# Run tests
npm run test
# Create a changeset
npm run changeset
MIT © jsPsych contributors