A local-first, single-file project scheduling simulator with WBS/Gantt planning, CPM, resource leveling, fixed milestones, sprints, and AI-assisted replanning.
Project Scheduler helps you test project plans against dependencies, milestones, sprint windows, and resource capacity. It runs entirely in your browser from a single HTML file, with no server or account required.
Live Demo | Downloadable HTML | Feature Overview | Hands-on Tutorial (Japanese) | JSON Format
Project Scheduler is a planning simulator, not a replacement for collaborative tools such as Jira or Backlog. Use it before entering tasks into those systems, or when a plan changes and you need to explore the impact of dependencies, fixed dates, and resource conflicts.
- Change estimates or dependencies and recalculate downstream dates.
- Identify critical tasks by viewing the critical path and float.
- Resolve overlapping assignments against weekly and monthly resource capacity.
- Keep planning data in your browser instead of sending it to an external service.
- Open the Live Demo.
- In the sample WBS, change the effort for
基本設計(Basic Design) from6to10. - Select
Run auto-schedulingin the upper-right corner. - Check how the downstream dates, projected completion date, and critical path change.
Use a current browser: Safari 16.4+, Chrome/Edge 111+, or Firefox 128+ (the minimum versions required by Tailwind CSS 4). Older browsers are not supported.
No build or installation is required. For offline use, open project_scheduler.html, select Download raw file on GitHub, and open the downloaded file in your browser.
To move a plan between devices, or between the Live Demo and the downloaded HTML, export it as JSON from the header and import it in the other environment.
The Live Demo is published in three variants:
| Page | URL | Interface language |
|---|---|---|
| Default | https://lhideki.github.io/project-scheduler/ | Your saved choice, otherwise your browser's language |
| English | https://lhideki.github.io/project-scheduler/en/ | Always opens in English |
| Japanese | https://lhideki.github.io/project-scheduler/ja/ | Always opens in Japanese |
The English and Japanese pages open in their own language even if you chose another language earlier. If you switch the language from the header on one of those pages, the address changes to the page for the new language, so reloading or bookmarking keeps your choice.
All three pages are served from the same site, so they share the plan saved in your browser. Switching between them shows the same project in a different language.
- Edit a WBS as an outline and view its Gantt chart against a working-day calendar that accounts for weekends and Japanese public holidays.
- Navigate cells with the arrow keys, copy and paste individual cells or rows, and undo or redo task edits. Continuous input is one Undo step when committed with Enter or a focus change; editing the same cell again creates a separate step.
- Add company holidays or extra working days in the
Calendartab to override weekends and public holidays. - Zoom the Gantt chart from days to weeks and months, hatch non-working days inside task bars, draw a progress line (inazuma line) against a chosen status date, and hover over or focus a bar to see its details in a tooltip.
- Model all four dependency types (FS, SS, FF, and SF) with lead and lag offsets.
- Calculate and visualize float and the critical path with the Critical Path Method (CPM).
- Switch milestones between flexible mode, scheduled forward from dependencies, and fixed mode, scheduled backward from a due date.
- Automatically level resources against weekly and monthly capacity limits. Work is allocated day by day from the earliest date with free capacity, so a task's duration stretches over the days its assignee is at capacity. Those unallocated days are hatched in the Gantt chart, and the tooltip explains why.
- Check each assignee's weekly workload against their capacity in the
Resourcestab. - Define sprints with start dates, end dates, and themes, and assign multiple sprints to a task.
- Flag conflicts between sprint windows and calculated task dates.
- Keep invalid dependency edits in the input with an explanation; the saved dependencies stay unchanged until the full input is valid. After auto-scheduling, review the changed-task count and any remaining constraints from a persistent result panel.
- Flag dependency problems in the WBS table and Gantt chart: circular dependencies (including cycles through groups), start dates that break a dependency, fixed milestones pushed past their due date, and links to deleted tasks.
- Inspect dependencies in a network (PERT) view.
- Copy the calculated schedule as a Mermaid Gantt chart, or copy the visible part of the Gantt chart as a PNG image.
- Save snapshots, compare multiple versions on a Gantt-style timeline, and restore an earlier state, including its saved resource-leveling setting. Restoring clears task Undo/Redo history. Older full snapshots without that setting retain the current toggle, so recalculated dates may differ from the saved comparison.
- Export and import the complete project, including tasks, resources, sprints, calendar overrides, the resource leveling setting, and version history, as JSON.
- Switch the interface between English and Japanese from the header. The first visit follows your browser's language, and your choice is remembered in the browser (it is not saved in the project JSON). The Live Demo also has English and Japanese pages that always open in that language. See Live Demo languages. Sample data and Japanese public holiday names stay in Japanese.
- Export a shared HTML file that embeds the current plan. See Share a snapshot as HTML.
- Use the included Claude Code Skill to let an AI agent adjust an exported plan directly. See AI-assisted replanning.
Click the name in the header to set or change it, then apply or cancel the edit (Enter/Escape also work). The header and browser tab show the name. Blank names display “Untitled project” in the selected language; that translated label is not stored.
Names are kept in browser storage, JSON, linked JSON, shareable HTML, and the CLI's proposed JSON, including projects with no tasks. Restoring a schedule version keeps the current project name. Changing a name does not rename existing files, change the schedule association or storage location, or create a separate project slot. Duplicate names are allowed.
New downloads use the applied project name as their default filename: Project Name_YYYY-MM-DD.json, Project Name-share_YYYY-MM-DD.html, and Project Name-gantt_YYYY-MM-DD.png (when PNG clipboard copying is unavailable or fails). Forbidden filename characters are replaced, control characters are removed, and long names are shortened without changing the stored name. Blank or unusable names keep the previous defaults (project-scheduler_…, project-scheduler-share_…, and gantt_…). You can still change the suggested name in the browser’s save dialog when enabled.
Existing nameless schemaVersion: 1 files remain readable. Use updated HTML and CLI versions together: older versions discard the new projectName field on re-export, and their schema rejects it. See import validation and compatibility.
When opened in a regular browser, the app automatically saves changes to that browser's localStorage after about 0.8 seconds. Data stays in that browser and on that device; it is not synchronized automatically with other browsers or devices.
Private browsing or clearing site data may delete the saved plan. Export important plans to JSON regularly as a backup.
The status below the header shows Unsaved changes, Saved in this browser, or Could not save. A saved status means both the latest plan and version history were written successfully. If a write fails, your edits stay on screen: use Back up as JSON before closing, or Retry saving. A newly added version is initially kept on screen and uses the same save status. Linked JSON and shared HTML explicitly show that automatic saving is off.
Saved projects with no tasks are restored together with their resources, sprints, calendar overrides, and leveling setting. If saved data cannot be read or validated, automatic saving pauses instead of overwriting it; retrying asks before replacing it with the current screen contents.
JSON imports validate the complete plan and version snapshots before asking to replace the current plan. Syntax errors and invalid fields are shown separately, with field paths to help correct the JSON. Failed or cancelled imports leave the current plan and history unchanged. See Import validation and compatibility.
Select Export shareable HTML from the Export menu to download a self-contained HTML file with the current plan embedded. Anyone can open it in a browser without the JSON file. It shows the plan as it was when you exported it.
The shared HTML opens in the recipient's language, like the downloadable HTML, even if you exported it from the English or Japanese page of the Live Demo. It does not save changes to localStorage. You can still edit the plan after opening it, but reloading the page restores the exported state. To keep your changes, export them as JSON.
You can link a JSON file synchronized by a desktop client such as Dropbox, Google Drive, or OneDrive by adding a schedule query parameter to the URL. The query value does not grant access to a local path. It is only a key that the browser uses to identify a file you explicitly select.
project_scheduler.html?schedule=%2FUsers%2Ftaro%2FDropbox%2Fschedules%2Fproject-a.json
- URL-encode the user's local path and pass it as the
schedulequery value. - On the first visit, select
Select JSONand choose the local file associated with that query. - In browsers that support the File System Access API, the app stores the file association in IndexedDB. It can reopen the file on later visits while permission remains available.
- Select
Reload latestto reopen the synchronized file after it changes.
While a linked JSON file is open, edits are not automatically saved to localStorage. You must select the file again if the browser does not support the File System Access API or if permission is lost. A real local path in an HTTP(S) URL may appear in access logs, so use a logical key such as a project name if the path is sensitive.
The repository includes the schedule-adjust Skill for Claude Code. It reads and writes exported Project Scheduler JSON (schemaVersion: 1), so you can ask an AI agent to handle requests such as:
- "Move this task back by two weeks and reschedule its dependents."
- "Level the plan so that the same person is not assigned to overlapping tasks."
- "Replan around a delay in work that has already started."
The included CLI (.claude/skills/schedule-adjust/cli.mjs) performs CPM recalculation, resource leveling, validation, and impact reporting. It requires Node.js 18 or later and no additional installation. The CLI itself does not overwrite JSON files. The Skill first reports the proposed changes, asks for approval, and writes them only after approval. Before writing, it saves the previous state in a versions[] snapshot that you can compare or restore in the app.
When Claude Code is opened in this repository, .claude/skills/schedule-adjust/ is available automatically as a project Skill. To use it elsewhere, install it as a Claude Code plugin:
/plugin marketplace add lhideki/project-scheduler
/plugin install schedule-adjust@project-schedulerIf you linked a local JSON file as described in Link a JSON file from a synced folder, select Reload latest after the agent edits it. Otherwise, export a JSON file, have the agent edit it, and import the result back into the app.
The same plugin bundles a second Skill, backlog-sync, that keeps an exported plan and a
Backlog project in sync through bee,
Nulab's official Backlog CLI. Install bee 1.1 or later and authenticate it first
(npm i -g @nulab/bee, then bee auth login).
- Scheduler → Backlog: create or update issues from the plan. Computed start and due
dates come from
schedule-adjust'srecalc, so the JSON format is unchanged. - Backlog → Scheduler: read issue status back into
progress, then hand off toschedule-adjustto replan and save.
Sync settings and the task-to-issue mapping live in a sidecar file next to the exported
JSON (<file>.backlog.json); the Project Scheduler JSON schema itself is not touched.
The Skill always shows a diff and asks for approval before writing to Backlog, and never
deletes issues automatically. See .claude/skills/backlog-sync/ for the mapping template.
See the JSON format reference for fields, types, and required properties. The reference is generated from the JSON Schema in the source code.
Imports currently accept only schemaVersion: 1. Different schema versions are not converted; schema-v1 JSON without newer optional fields remains supported.
project_scheduler.html is a generated artifact. The build bundles the React source from src/entry.jsx with esbuild and embeds it with the Tailwind CSS output into a single HTML file. Do not edit the generated HTML directly; rebuild it after changing the source.
Pushing to master runs the tests and build in GitHub Actions, then publishes the generated HTML to the Live Demo on GitHub Pages as the Default, English, and Japanese pages. Pull requests run the same tests and build, and fail if a generated file is not up to date.
Tailwind CSS 4 uses the separate @tailwindcss/cli package. src/input.css explicitly scans JSX only, and src/theme.css keeps the established colors and fonts. Keep the CLI/framework versions aligned and regenerate the single HTML after CSS changes.
- Node.js
^20.19.0 || ^22.12.0 || >=24.0.0for development and tests: 20.x from 20.19, 22.x from 22.12, or 24 and later. Node.js 21 and 23 are not supported. This is the range that Vitest 4 and Vite 8 both support. GitHub Actions uses Node.js 24. - The bundled Skill CLI (
cli.mjs) itself runs on Node.js 18 or later.
npm install
npm run test
npm run build
npx playwright install --with-deps chromium
npm run test:browserBrowser tests check the built HTML in Chromium and start a local server on 127.0.0.1:4173. Pull-request CI also runs them and uploads screenshots, failure traces, and the HTML report as browser-evidence-<commit>. See verification details.
npm run build runs these six steps:
| Command | Output |
|---|---|
npm run build:js |
Bundles and minifies src/entry.jsx into dist/bundle.js. |
npm run build:css |
Generates dist/output.css from src/input.css. |
npm run build:html |
Embeds the JavaScript and CSS into template.html and generates project_scheduler.html. |
npm run build:docs |
Generates docs/json-format.md from the JSON Schema in the source code. |
npm run build:agent |
Bundles src/agent/cli.js into .claude/skills/schedule-adjust/cli.mjs. |
npm run build:readme |
Generates README.md from README.en.md. |
npm run build:pages generates the Live Demo pages from project_scheduler.html into _site/ (index.html, ja/index.html, and en/index.html). It is not part of npm run build; GitHub Actions runs it before publishing. Set PAGES_BASE_URL to change the public URL used in the hreflang links.
README.en.md (English) and README.ja.md (Japanese) are edited by hand. README.md is generated from README.en.md by npm run build:readme: it has the same content, except that its Live Demo links point to the Default page. Do not edit README.md directly. npm run test fails if it is out of date.
.
├── src/
│ ├── App.jsx # Application state and top-level composition
│ ├── components/ # UI components, including WBS and Gantt views
│ ├── lib/ # CPM, calendar, dependencies, JSON logic, and tests
│ ├── dom/ # DOM helpers such as pointer dragging
│ ├── agent/ # Skill CLI, reusing the scheduling logic in src/lib
│ ├── entry.jsx # React entry point
│ ├── input.css # Tailwind CSS input
│ └── storage.js # window.storage and localStorage integration
├── scripts/ # HTML, Live Demo pages, README, JSON documentation, and Skill CLI generators
├── docs/ # JSON reference and README images
├── .claude/skills/ # Claude Code Skills (schedule-adjust, backlog-sync)
├── .claude-plugin/ # Plugin marketplace metadata
├── template.html # Source template for the distributable HTML
└── project_scheduler.html # Generated distributable
- Real-time multi-user editing and automatic cross-device synchronization are not supported. Use JSON export and import to share or transfer a plan.
- The working-day calendar uses a simplified implementation of Japanese public holidays. Use the
Calendartab to correct individual dates or add company-specific holidays. - Undo and Redo retain the last 100 task operations, not changes to resources, sprints, or the calendar. Inside an input, Ctrl/Cmd+Z uses the browser’s text Undo; use the toolbar or move focus outside inputs for task Undo/Redo. Restoring a version clears task history.
Please report bugs and feature requests in GitHub Issues. If Project Scheduler is useful to you, a Star is always appreciated.



