A VS Code extension that lets students compare their local project against a final solution hosted on GitHub, using a native TreeView UI with file-by-file diffs.
Built for Dicoding Academy โ an EdTech platform where students learn by building real projects.
The extension auto-activates when a project contains a .vscode/course-project.json config file. It reads the GitHub URL, branch, and target folder to fetch only the relevant solution files.
Uses sparse-checkout to download only the specific folder needed for the current project โ saving bandwidth and time by ignoring the rest of the monorepo.
A custom panel that visually lists all differing files, grouped by category (Added, Modified, Deleted) with themed icons. Clicking a file opens VS Code's native side-by-side diff editor.
- Full Project Diff โ Compare the entire local project against the solution tree
- Single File Diff โ Compare just the currently open file via right-click context menu or the editor title bar icon
When the student saves, creates, or deletes a file, the TreeView automatically updates within 300ms (debounced for performance).
Silently checks for solution updates in the background. If a newer version is available, a toast notification prompts the student to update.
- Cross-platform line endings โ Normalizes CRLF/LF before comparison
- Binary file detection โ Scans first 8KB for null bytes; binary files are flagged and prevented from opening in the text diff editor
- Graceful Git process management โ Cross-platform process cleanup (Windows
taskkill/ POSIX signals) with timeouts - Failed pulls auto-recover โ Nukes broken cache and re-clones from scratch
Pedagogical design: There is intentionally no "Apply Changes" button. Students must manually read the diff and copy code โ this encourages deeper learning.
- VS Code โฅ 1.85.0
- Git โฅ 2.28 (required for
--filter=blob:nonesparse-checkout) - Node.js โฅ 18 (for development only)
- Install the extension from the VS Code Marketplace (or install the
.vsixfile manually) - Open a project that contains a
.vscode/course-project.jsonfile - The extension activates automatically โ look for the Code Diff-Checker panel in the sidebar
- Run "Fetch Solution" from the Command Palette (
Ctrl+Shift+PโCode Diff-Checker: Fetch Solution) or click the download icon in the TreeView header - Click on any file in the TreeView to see the diff
Create a .vscode/course-project.json file in your project root:
{
"repoUrl": "https://github.com/dicodingacademy/a159-flutter-pemula-labs.git",
"branch": "main",
"targetFolder": "navigation_project",
"ignorePaths": ["build/", "*.iml"]
}| Field | Required | Description |
|---|---|---|
repoUrl |
โ | GitHub HTTPS clone URL |
branch |
โ | Branch containing the solution |
targetFolder |
โ | Folder path within the repo to compare against |
ignorePaths |
โ | Glob patterns for files to exclude from comparison (defaults to []) |
| Command | Description | Access |
|---|---|---|
| Fetch Solution | Clone/update the solution and compute diff | Command Palette, TreeView header, Status Bar |
| Compare Current File | Diff the active editor file against the solution | Right-click context menu, Editor title bar |
| Refresh Diff | Re-compute diff from existing cache (no network) | TreeView header |
| Clear Cache | Delete the cached solution and reset the TreeView | TreeView header menu |
src/
โโโ extension.ts # Entry point โ registers commands, orchestrates modules
โโโ types.ts # Shared TypeScript interfaces
โโโ constants.ts # Timeouts, ignore patterns, min Git version
โโโ config.ts # Parses & validates .vscode/course-project.json
โโโ processManager.ts # Cross-platform child_process wrapper with timeout
โโโ gitService.ts # Git operations (clone, fetch, pull, version check)
โโโ cacheManager.ts # Cache lifecycle (MD5-hashed directories)
โโโ diffEngine.ts # Walks both trees, classifies added/modified/deleted
โโโ treeViewProvider.ts # Sidebar TreeView UI with themed icons
โโโ test/
โโโ config.test.ts # 9 tests โ config validation
โโโ gitService.test.ts # 9 tests โ Git version validation
โโโ diffEngine.test.ts # 9 tests โ diff classification, binary detection
โโโ __mocks__/vscode.js # Minimal vscode API mock
โโโโโโโโโโโโโโโโ โโโโโโโโโโโโโโโโ โโโโโโโโโโโโโโโโโโ
โ config.ts โโโโโโถโ gitService.tsโโโโโโถโ cacheManager.tsโ
โ (load JSON) โ โ (sparse clone)โ โ (MD5 cache) โ
โโโโโโโโโโโโโโโโ โโโโโโโโฌโโโโโโโโ โโโโโโโโโโโโโโโโโโ
โ
โผ
โโโโโโโโโโโโโโโโโโ โโโโโโโโโโโโโโโโโโโโ
โ diffEngine.ts โโโโโโถโtreeViewProvider.tsโ
โ (walk & diff) โ โ (sidebar UI) โ
โโโโโโโโโโโโโโโโโโ โโโโโโโโโโโโโโโโโโโโ
| Decision | Rationale |
|---|---|
| Git โฅ 2.28 required | --filter=blob:none has bugs in 2.25โ2.27 |
taskkill /pid /T /F on Windows |
process.kill() sends POSIX signals that crash the Extension Host |
| Cache uses MD5 hash of config | Ensures per-project isolation in globalStorageUri |
Only .vscode/course-project.json is ignored |
The rest of .vscode/ (like launch.json) can be diffed |
| Binary detection via null-byte scan | First 8KB checked โ prevents VS Code from rendering binary garbage |
| Failed pulls auto-nuke cache | Guarantees a clean state on next attempt |
git clone https://github.com/ianindratama/code-diffchecker-extension.git
cd code-diffchecker
npm install# Compile (single build via esbuild)
npm run compile
# Watch mode (auto-rebuild on changes)
npm run watch
# Run unit tests
node run-tests.js
# Lint
npm run lint- Open this project in VS Code
- Press F5 to launch the Extension Development Host
- In the new window, open a project with a
.vscode/course-project.jsonfile - Test the extension commands and TreeView
npx @vscode/vsce packageThis generates a .vsix file that can be installed manually or published to the VS Code Marketplace.
27 unit tests across three modules โ all passing.
| Module | Tests | What's Covered |
|---|---|---|
| Config Loader | 9 | Valid config, missing fields, invalid URL, malformed JSON |
| Git Service | 9 | Version validation (2.28+ required, Windows format, edge cases) |
| Diff Engine | 9 | Add/modify/delete classification, ignore layers, binary detection, CRLF normalization |
# Run all tests
node run-tests.jscode-diffchecker-extension/
โโโ .vscode/
โ โโโ launch.json # F5 debug config
โ โโโ tasks.json # Watch build task
โโโ src/ # TypeScript source
โ โโโ test/ # Unit tests + mocks
โ โโโ *.ts # Core modules (see Architecture)
โโโ out/ # Compiled output (gitignored)
โโโ package.json # Extension manifest
โโโ tsconfig.json # TypeScript config (strict mode)
โโโ esbuild.js # Build script
โโโ run-tests.js # Test runner
โโโ .eslintrc.json # Linting rules
โโโ .vscodeignore # Packaging exclusions
- Fork the repository
- Create a feature branch (
git checkout -b feature/my-feature) - Commit your changes (
git commit -m 'Add some feature') - Push to the branch (
git push origin feature/my-feature) - Open a Pull Request
Please ensure:
- All existing tests pass (
node run-tests.js) - TypeScript compiles with zero errors (
npm run compile) - Code follows the existing ESLint rules (
npm run lint)
This project is licensed under the MIT License โ see the LICENSE file for details.
Built for Dicoding Academy to help students learn by comparing their work against reference solutions in a guided, educational workflow.