Build a typed CLI from scratch with Commander.js + Zod

📰 Dev.to · Cris Mihalache

Learn to build a typed CLI from scratch using Commander.js and Zod, improving code quality and maintainability

intermediate Published 22 Apr 2026
Action Steps
  1. Install Commander.js and Zod using npm or yarn to set up the project environment
  2. Create a new TypeScript project and configure it to work with Commander.js and Zod
  3. Define commands and options using Commander.js and validate them with Zod
  4. Implement command handlers and integrate them with the validated options
  5. Test the CLI tool to ensure it works as expected and handles errors properly
Who Needs to Know This

This tutorial is beneficial for software engineers and developers who work with Node.js, TypeScript, and CLI tools, as it enhances their skills in building robust and maintainable command-line interfaces.

Key Insight

💡 Using Commander.js and Zod together enables you to create typed CLIs, which enhances code quality, maintainability, and reduces errors

Share This
🚀 Build a typed CLI from scratch with Commander.js + Zod! Improve code quality and maintainability with this step-by-step guide 📚

Key Takeaways

Learn to build a typed CLI from scratch using Commander.js and Zod, improving code quality and maintainability

Full Article

Title: Build a typed CLI from scratch with Commander.js + Zod

URL Source: https://dev.to/f3rnox/build-a-typed-cli-from-scratch-with-commanderjs-zod-4oj6

Published Time: 2026-04-22T23:03:34Z

Markdown Content:
# Build a typed CLI from scratch with Commander.js + Zod - DEV Community
[Skip to content](https://dev.to/f3rnox/build-a-typed-cli-from-scratch-with-commanderjs-zod-4oj6#main-content)

[![Image 1: DEV Community](https://media2.dev.to/dynamic/image/quality=100/https://dev-to-uploads.s3.amazonaws.com/uploads/logos/resized_logo_UQww2soKuUsjaOGNB38o.png)](https://dev.to/)

[Powered by Algolia](https://www.algolia.com/developers/?utm_source=devto&utm_medium=referral)

[Log in](https://dev.to/enter?signup_subforem=1)[Create account](https://dev.to/enter?signup_subforem=1&state=new-user)

## DEV Community

![Image 2](https://assets.dev.to/assets/heart-plus-active-9ea3b22f2bc311281db911d416166c5f430636e76b15cd5df6b3b841d830eefa.svg)0 Add reaction

![Image 3](https://assets.dev.to/assets/sparkle-heart-5f9bee3767e18deb1bb725290cb151c25234768a0e9a2bd39370c382d02920cf.svg)0 Like ![Image 4](https://assets.dev.to/assets/multi-unicorn-b44d6f8c23cdd00964192bedc38af3e82463978aa611b4365bd33a0f1f4f3e97.svg)0 Unicorn ![Image 5](https://assets.dev.to/assets/exploding-head-daceb38d627e6ae9b730f36a1e390fca556a4289d5a41abb2c35068ad3e2c4b5.svg)0 Exploding Head ![Image 6](https://assets.dev.to/assets/raised-hands-74b2099fd66a39f2d7eed9305ee0f4553df0eb7b4f11b01b6b1b499973048fe5.svg)0 Raised Hands ![Image 7](https://assets.dev.to/assets/fire-f60e7a582391810302117f987b22a8ef04a2fe0df7e3258a5f49332df1cec71e.svg)0 Fire

0 Jump to Comments 0 Save Boost

Copy link

Copied to Clipboard

[Share to X](https://twitter.com/intent/tweet?text=%22Build%20a%20typed%20CLI%20from%20scratch%20with%20Commander.js%20%2B%20Zod%22%20by%20Cris%20Mihalache%20%23DEVCommunity%20https%3A%2F%2Fdev.to%2Ff3rnox%2Fbuild-a-typed-cli-from-scratch-with-commanderjs-zod-4oj6)[Share to LinkedIn](https://www.linkedin.com/shareArticle?mini=true&url=https%3A%2F%2Fdev.to%2Ff3rnox%2Fbuild-a-typed-cli-from-scratch-with-commanderjs-zod-4oj6&title=Build%20a%20typed%20CLI%20from%20scratch%20with%20Commander.js%20%2B%20Zod&summary=The%20problem%20with%20untyped%20CLIs%20%20%20Commander.js%20is%20great%20for%20parsing%20arguments%2C%20but%20it%20hands...&source=DEV%20Community)[Share to Facebook](https://www.facebook.com/sharer.php?u=https%3A%2F%2Fdev.to%2Ff3rnox%2Fbuild-a-typed-cli-from-scratch-with-commanderjs-zod-4oj6)[Share to Mastodon](https://s2f.kytta.dev/?text=https%3A%2F%2Fdev.to%2Ff3rnox%2Fbuild-a-typed-cli-from-scratch-with-commanderjs-zod-4oj6)

[Share Post via...](https://dev.to/f3rnox/build-a-typed-cli-from-scratch-with-commanderjs-zod-4oj6#)[Report Abuse](https://dev.to/report-abuse)

[![Image 8: Cover image for Build a typed CLI from scratch with Commander.js + Zod](https://media2.dev.to/dynamic/image/width=1000,height=420,fit=cover,gravity=auto,format=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fmg625gz5dy8lx45i68tp.png)](https://media2.dev.to/dynamic/image/width=1000,height=420,fit=cover,gravity=auto,format=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fmg625gz5dy8lx45i68tp.png)

[![Image 9: Cris Mihalache](https://media2.dev.to/dynamic/image/width=50,height=50,fit=cover,gravity=auto,format=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F3864439%2Fc7316899-0147-4001-9123-96a6db351b94.png)](https://dev.to/f3rnox)

[Cris Mihalache](https://dev.to/f3rnox)
Posted on Apr 22

# Build a typed CLI from scratch with Commander.js + Zod

[#node](https://dev.to/t/node)[#typescript](https://dev.to/t/typescript)[#cli](https://dev.to/t/cli)[#webdev](https://dev.to/t/webdev)

## [](https://dev.to/f3rnox/build-a-typed-cli-from-scratch-with-commanderjs-zod-4oj6#the-problem-with-untyped-clis) The problem with untyped CLIs

Commander.js is great for parsing arguments, but it hands you everything as
Read full article → ← Back to Reads