A purpose-built calendar and deadline manager that integrates directly with Canvas LMS. I originally built this for myself, but figured it might be useful to other students.
Canvas Task Manager pulls assignments from Canvas LMS via their API and gives you a clean, filterable calendar view where you can actually manage your work instead of stressing over deadlines.
Think of it as a layer between you and Canvas that lets you:
- Filter the noise - Systematically approve/reject assignments as they come in
- Track progress - Status assignments as incomplete → in progress → complete
- Submit directly - Submit assignments through CTM with verification checks to prevent ghost submissions
- Cross-reference - Link related assignments together using @mentions in notes
Canvas's built-in calendar has two major problems:
- No status tracking - You can't mark things as "in progress" or "complete." Every assignment is just there.
- No granular filtering - If your course has messy assignment structures, you're stuck with all the noise. Every discussion post, every reading, every junk cluttering your view.
CTM fixes this by giving you an approval workflow: assignments come in, you decide what's actually worth tracking, and only those show up on your calendar.
- Choose Your Mode:
- Sign in - Use OAuth2 through Clerk for cloud-synced data across devices
- Guest Mode - Use CTM locally without an account (data stays in your browser)
- Canvas Integration - Add your Canvas URL and API token in Settings
- Fetch Assignments - Hit the refresh button to pull assignments from Canvas
When you fetch assignments, CTM shows them in a pending sidebar. For each assignment:
- Review details - See the full description, due date/time, assignment type, and points
- Modify if needed - Adjust the title, date, class, or notes before importing
- Approve or Reject - Accept it into your calendar or reject it (rejected items won't show up again)
This filters out the noise. If your professor posts 20 "optional reading" assignments, you can reject them all and focus on what actually matters.
Once approved, assignments appear as events on your calendar:
- Drag-and-drop - Move events between days
- Status tracking - Click an event to mark it incomplete/in progress/complete
- Color coding - Events are colored by class for quick visual scanning
- Filtering - Toggle status filters (show/hide completed tasks) and class filters
- Cross-referencing - Use @mentions in the notes section to link related assignments
- Direct submission - Submit assignments directly from the event modal (with Canvas verification)
Cmd/Ctrl + K- Open Spotlight (Search)Cmd/Ctrl + ,- Open settingsCmd/Ctrl + J- Create new eventR- Fetch Canvas Assignments- Arrow keys - Navigate months
- Node.js (v16+)
- Canvas LMS account with API access
- Clerk account for authentication (free tier works)
# Clone the repo
git clone https://github.com/ansidian/Canvas-LMS-Task-Manager.git
cd Canvas-LMS-Task-Manager
# Install dependencies (both root and client)
npm run setup
# Initialize the database
npm run db:init
# Start development server
npm run devThe app will run on http://localhost:5173 (client) with the API server on http://localhost:3001.
You'll need .env files in two locations:
Root directory (.env) - For the server:
# Required for Clerk authentication
CLERK_SECRET_KEY=your_clerk_secret_key
# Optional: For production deployment with Turso cloud database
TURSO_DATABASE_URL=your_turso_db_url
TURSO_AUTH_TOKEN=your_turso_auth_tokenClient directory (client/.env) - For the frontend:
# Required for Clerk authentication
VITE_CLERK_PUBLISHABLE_KEY=your_clerk_publishable_keyNote: For local development, CTM uses a local SQLite database at server/db/canvas-tasks.db. Turso environment variables are only needed for production deployments.
- Log into Canvas
- Go to Account → Settings
- Scroll to "Approved Integrations"
- Click "+ New Access Token"
- Give it a name (e.g., "CTM") and generate
- Copy the token and paste it into CTM's Settings modal
- Frontend: React 19, Vite, Mantine UI v8
- Backend: Express.js
- Libraries Framer Motion (transitions), Sonner (Toast Notifications), TipTap (Notes section), DnD Kit, Day.js, Tippy.js (for @mention).
- Database: LibSQL/Turso (SQLite-compatible)
- Auth: Clerk (OAuth2)
- Deployment: Render.com
The frontend was designed from the start to keep App lean and put state where it naturally belongs:
- Contexts own distinct state domains (events, UI state, filters, onboarding).
- Hooks package workflows like Canvas sync/reconcile/fetch and settings modal state.
- Local storage is intentionally limited to lightweight UI preferences (filters, onboarding status, last fetch timestamp, pending cache).
- Credential storage:
- Signed-in users - Canvas URL/token are saved in your user settings (database) and are not stored in localStorage
- Guest mode - Canvas credentials are stored in localStorage only; your events, classes, and other data never leave your browser
- API proxying - Canvas API calls are proxied through the backend to avoid CORS issues. For signed-in users, credentials come from the database; for guest mode, credentials are passed from localStorage via request headers (the server doesn't store them)
- OAuth2 authentication - Clerk handles all auth for signed-in users, so no password management needed
- Submission verification - Before submitting assignments, CTM verifies with Canvas to prevent ghost submissions
This is a personal project, but if you find bugs or have feature ideas, feel free to open an issue. Pull requests are welcome if you want to add something useful.
Q: Will this work with my school's Canvas instance?
A: As long as your school uses Canvas LMS and allows API access, yes. CTM uses the standard Canvas API.
Q: Does this replace Canvas?
A: No. It's a task management layer on top of Canvas. You still use Canvas for course content, announcements, etc.
Q: What happens if I reject an assignment by mistake?
A: Rejected items are stored in the database. Currently there is no way to restore rejected items without invoking 'Reset All Data' in Settings → Help.
Q: Can I use this without Canvas?
A: You can manually create events without connecting to Canvas, but the main value is in the Canvas integration.
Q: Is my data private?
A: It depends on how you use CTM:
- Signed-in users - Your Canvas API token and assignment data are saved in the database (scoped to your Clerk user ID). Data syncs across devices.
- Guest mode - All your data (credentials, events, classes) is stored in your browser's localStorage only. Canvas API calls are still proxied through the server to avoid CORS issues, but the server doesn't store any guest data—credentials are passed via headers and discarded after the request.
Q: What's the difference between signing in and guest mode?
A: Signing in syncs your data to the cloud, so you can access it from any device. Guest mode keeps everything in your browser's localStorage—more private, but if you clear your browser data or switch devices, your data won't carry over.





