A LeetCode-style coding platform built exclusively for MuleSoft DataWeave developers.
Practice data transformations, compete in timed contests, and sharpen your skills with AI-generated problems — all in a browser-based Monaco editor connected to a live DataWeave 2.0 compiler.
Stop practicing transformations in a scratch Anypoint project you'll never open again.
Solve real problems. Race the clock. Climb the leaderboard. Let AI throw new challenges at you until %dw 2.0 feels like a second language.
Every MuleSoft developer knows the feeling: you can wire up an API in your sleep, but hand you a gnarly groupBy → pluck → reduce chain under interview pressure and suddenly the docs are open in three tabs.
DataWeave is a language. Languages get sharp with reps, not tutorials.
DWCode is the dojo. It gives you an endless supply of curated and AI-generated transformation puzzles, a real compiler to check your work against hidden test cases, and a scoreboard that turns "I should practice more" into "I'm rank #3 and I'm not stopping."
Built by the community, for the community. 💜
The main event. A clean split-pane battle station:
- Split-pane layout: Problem description | Monaco editor | Console — everything in one view, zero context-switching
- Run code against custom JSON input, or click Submit to evaluate all test cases at once
- Real-time pass/fail feedback with per-test-case diff output — see exactly where your output drifted
- Built-in countdown timer to simulate interview pressure (or just keep you honest)
- Bookmark any problem for later revision
- Reveal Solution toggle with optional hints
- My Notes tab — auto-saved, per-problem markdown notes so future-you remembers the trick
- Discussion tab — comment thread per problem
Never run out of problems again.
- One-click generation via Google Gemini 2.5 Flash
- Configure difficulty (Easy / Medium / Hard), category, and an optional topic
- Returns a full problem: description, examples, constraints, starter code, test cases, hidden test cases, hints, and a reference solution
- Problems are saved immediately to the database and appear in the problem list
- Create time-boxed contests with any subset of problems
- Public or invite-code-only visibility
- Auto-computed status:
upcoming→active→ended - Participant scoring: Hard ×5, Medium ×3, Easy ×1
- Global ranking based on weighted score across all accepted submissions
- Per-user breakdown: Easy / Medium / Hard solved, acceptance rate, total submissions
- Live aggregation — no manual sync required
- Standalone editor with no problem constraints — bring your own chaos
- Three-panel layout: Input payload | DataWeave script | Output
- Instant execution, copy-to-clipboard, reset, and execution time display
- Community blog with full CRUD
- Write posts using a rich text editor; published posts are publicly visible
- Progress overview: total solved, by difficulty, bookmarks
- Submission history and personal stats
- Gamification layer: earn coins for accepted solutions
- Transaction history visible in user profile
- Role management and user administration via dedicated
/adminroutes - Protected by Clerk authentication and custom role checks
Every piece was chosen to keep the loop tight: write DataWeave → run against a real compiler → get instant truth.
| Layer | Technology |
|---|---|
| Framework | Next.js 16 (App Router) |
| Language | TypeScript 5 |
| UI | Tailwind CSS v4, shadcn/ui, Lucide Icons |
| Editor | Monaco Editor (@monaco-editor/react) |
| Auth | Clerk (@clerk/nextjs) |
| Database | MongoDB via Mongoose |
| AI | Google Gemini 2.5 Flash (@google/genai) |
| State | Zustand |
| Compiler Backend | DataWeave runtime (Docker / external service) |
| Containerisation | Docker Compose |
| Font | Geist (via next/font) |
From
git cloneto green checkmarks in five steps.
- Node.js ≥ 18
- Docker (for MongoDB and optional DataWeave compiler backend)
- A Clerk account — clerk.com
- A Google Gemini API key — ai.google.dev
The Next.js application lives in the client/ directory; there is no root package.json.
All npm commands below run from client/.
git clone https://github.com/your-username/dwcode.git
cd dwcode/client
npm installCreate client/.env.local and fill in your values:
# from the repo root
touch client/.env.local# client/.env.local
# MongoDB connection string
MONGODB_URI=mongodb://localhost:27017/dwcode
# Google Gemini API key (for AI problem generation)
GEMINI_API_KEY=your_gemini_api_key_here
# Clerk authentication keys (from your Clerk dashboard)
NEXT_PUBLIC_CLERK_PUBLISHABLE_KEY=pk_test_...
CLERK_SECRET_KEY=sk_test_...
# Clerk redirect paths
NEXT_PUBLIC_CLERK_SIGN_IN_URL=/sign-in
NEXT_PUBLIC_CLERK_SIGN_UP_URL=/sign-upFrom the repo root (docker-compose.yml lives there, not in client/):
docker-compose up -dThis spins up a MongoDB instance at localhost:27017 with a persistent volume.
The code execution engine is a separate DataWeave runtime service. By default the app points to https://dwlbackend.onrender.com. To run it locally, start the companion Docker container and update DATAWEAVE_BACKEND_URL in your env file accordingly.
cd client
npm run devThe app starts on http://localhost:8000 — open it, pick a problem, and start transforming. 🎉
The repo root holds infrastructure and docs; the entire Next.js application lives in client/.
dwcode/
├── client/ # ◀ THE NEXT.JS APP (run npm here)
│ ├── app/ # App Router pages & API routes
│ │ ├── api/ # REST API handlers
│ │ │ ├── execute/ # DataWeave code execution proxy
│ │ │ ├── transform/ # Playground execution proxy (multi-input)
│ │ │ ├── generate/ # AI problem generation (Gemini)
│ │ │ ├── problems/ # Problem CRUD
│ │ │ ├── submissions/ # Submission tracking
│ │ │ ├── contests/ # Contest management
│ │ │ ├── leaderboard/ # Score aggregation
│ │ │ ├── bookmarks/ # Bookmark toggle
│ │ │ ├── notes/ # Per-problem notes
│ │ │ ├── coins/ # Gamification coins
│ │ │ ├── blog/ # Blog posts
│ │ │ ├── comments/ # Problem discussion threads
│ │ │ ├── profile/ # Profile, username, follow
│ │ │ ├── auth/github/ # GitHub OAuth flow
│ │ │ ├── playground/ # Share, AI insights, GitHub import/push
│ │ │ └── admin/ # Admin: users & roles
│ │ ├── problems/[slug]/ # Problem workspace (split-pane editor)
│ │ ├── playground/ # Free DataWeave playground
│ │ ├── contests/ # Contest list & detail
│ │ ├── leaderboard/ # Global leaderboard
│ │ ├── blog/ # Blog list, detail & editor
│ │ ├── profile/ # User profile page
│ │ ├── create/ # Manual problem creation form
│ │ └── admin/ # Admin dashboard
│ ├── components/ # Shared UI components (Navbar, Comments, etc.)
│ ├── models/ # Mongoose schemas (Problem, Submission, Contest…)
│ ├── lib/ # Database connection, config, utilities
│ ├── public/ # Static assets
│ ├── __tests__/ # Vitest property-based tests
│ ├── proxy.ts # Clerk middleware (Next.js 16 naming)
│ ├── package.json # Dependencies & scripts
│ ├── next.config.ts # output: "standalone"
│ ├── tsconfig.json # "@/*" → client root
│ └── .env.local # Local secrets (gitignored)
├── .github/workflows/ # CI (runs with working-directory: client)
├── .agents/ · .kiro/ # Agent skills & feature specs
├── docker-compose.yml # MongoDB container
├── Dockerfile # App image (build context = repo root)
└── README.md
| Method | Route | Description |
|---|---|---|
GET/POST |
/api/problems |
List or create problems |
POST |
/api/execute |
Run DataWeave code |
POST |
/api/generate |
Generate problem with AI |
GET/POST |
/api/contests |
List or create contests |
GET |
/api/leaderboard |
Fetch ranked leaderboard |
POST |
/api/submissions |
Submit a solution |
GET/POST |
/api/bookmarks |
Toggle bookmark |
GET/PUT |
/api/notes |
Read/write problem notes |
GET |
/api/coins |
User coin balance |
GET/POST |
/api/blog |
Blog post management |
GET/POST |
/api/comments |
Problem discussion |
Start only MongoDB (from the repo root):
docker-compose up -dBuild and run the full app in Docker. The build context is the repo root (the Dockerfile
copies from client/), so run this from the root, not from client/:
docker build -t dwcode .
docker run -p 3000:3000 --env-file client/.env.local dwcodeNote: the image listens on port 3000 (
ENV PORT 3000in the Dockerfile), whereasnpm run devandnpm startuse port 8000. Map ports accordingly.
The two halves deploy independently.
| Part | Platform | Config | Why |
|---|---|---|---|
client/ |
Vercel | client/vercel.json | Native Next.js hosting |
server/ |
Render | render.yaml | Long-lived Express process |
The backend cannot run on Vercel. It calls app.listen(), holds a MongoDB
connection pool, and runs a periodic upstream heartbeat — none of which survive a
serverless runtime that freezes between invocations.
Create the project, then set Root Directory to client in Settings → General.
That one setting is what makes the monorepo work; everything else is auto-detected.
Required environment variables:
NEXT_PUBLIC_CLERK_PUBLISHABLE_KEY
CLERK_SECRET_KEY
NEXT_PUBLIC_API_URL # the deployed Render URL
NEXT_PUBLIC_APP_URL # the deployed Vercel URL
MONGODB_URI # until the API migration finishes
Dashboard → Blueprints → New Blueprint Instance, pointed at render.yaml.
It declares the build/start commands, /health as the health check, and every
environment variable. Secrets are marked sync: false, so Render prompts for them
instead of reading values from git.
After the first deploy, two values must agree or the browser will be blocked by CORS:
CORS_ALLOWED_ORIGINSon Render must contain the Vercel origin.NEXT_PUBLIC_API_URLon Vercel must be the Render URL.
The service also keeps the frozen legacy endpoints — POST /api/transform,
/health, /healthcheck — byte-compatible with the original server.js, so
existing callers continue to work unchanged.
Want to help shape where DWCode goes next? These are open for the taking:
- 📅 Daily challenge streaks (keep the muscle warm)
- 🏢 Company-tagged problem sets for interview prep
- 🧵 DataWeave "pattern of the week" community writeups
- 🥇 Team leagues and seasonal contests
Have an idea? Open an issue and let's talk.
DWCode is open source — because the best integrations are the ones we build together. 🐴💜
We didn't build DWCode to lock it away behind a paywall. We built it because we are the MuleSoft community — and every Muley deserves a place to sharpen their DataWeave without spinning up yet another throwaway Mule app.
So here it is. Free. Open. Yours. Fork it, self-host it, remix it, ship it. This is our contribution to the flow — now add yours.
Every Muley makes the mule stronger. Here's how you can plug in:
- 🧩 Add a problem — dreamt up a devious transformation? Drop it in and stump the leaderboard.
- 🐛 Squash a bug — see something misbehaving? A PR is worth a thousand issues.
- 📖 Write a blog post — teach a DataWeave pattern that took you three hours to crack.
- ✨ Build a feature — the roadmap above is a menu, not a limit.
- ⭐ Star the repo — the cheapest, kindest way to say "keep going."
%dw 2.0
output application/json
var community = payload.developers
---
{
status: "open source, forever",
gift: "DWCode",
from: "us",
to: "the MuleSoft community",
yourMove: community map (dev) -> dev ++ { contributed: true }
}An API is only as good as the community that connects to it. Same goes for a practice platform. 🔌
DWCode gets better every time a MuleSoft dev throws in a problem, fixes a bug, or writes a blog post. Jump in:
- Fork the repo and create a feature branch:
git checkout -b feat/your-feature - Install from the repository root — this is an npm workspace:
npm install - Make your changes, then verify:
npm run typecheck && npm run lint && npm test && npm run build - Open a pull request with a clear description
CONTRIBUTING.md has the full guide — repository layout, the rule about never hand-writing a problem's expected output, database migration conventions, and the gotchas that bite newcomers.
Please also read our Code of Conduct.
Every contribution — a single test case or a whole new feature — makes the whole community sharper. 🙌
MIT — feel free to use, fork, and extend. Go build something great.
Found a security issue? Please report it privately — see SECURITY.md.
%dw 2.0
output application/json
---
{
project: "DWCode",
builtWith: "💜",
gift: "open source, to the MuleSoft community",
from: "one Muley to every Muley",
message: "Keep weaving. Keep shipping. Keep leveling up.",
yourTurn: "fork it → improve it → give it back"
}⭐ If DWCode helped you level up, drop a star — it fuels the mission. ⭐