Series: Building EDIFlow - A Clean Architecture Journey in TypeScript (Part 1/6)
Author: EDIFlow
Published: February 2026
Reading Time: ~7 minutes
1. Introduction - The Problem π€
I've been working in data integration for over 20 years. SOAP, REST APIs, and yesβEDI. Lots of EDI.
If you've ever worked with EDIFACT, you know the pain:
UNH+1+ORDERS:D:96A:UN'
BGM+220+ORDER12345+9'
DTM+137:20240201:102'
NAD+BY+BUYER123::92'
What does BGM+220 mean? What is DTM+137? What's ::92?
This is the "old school EDI" world:
- β No human-readable names
- β Just codes and tags (BGM, NAD, DTM...)
- β Makes onboarding new developers incredibly hard
And the existing parsers? They don't help much:
// β Typical EDI Parser - Generic segments
const bgm = message.segments.find(s => s.tag === 'BGM');
const docNumber = bgm?.elements[1]?.value; // What is element[1]? π€·
No type safety. No IntelliSense. No business logic.
After 20+ years of this, I had enough. I wanted to build an EDI library that:
- β Maps to type-safe TypeScript business objects
- β Uses Clean Architecture principles
- β Makes EDI development enjoyable (yes, really!)
So I started EDIFlow.
But here's the honest truth: I didn't just want to build a library. I wanted to LEARN Clean Architecture by doing.
2. Why Clean Architecture? π
The Honest Answer: I Wanted to Learn It!
I first encountered Clean Architecture around 2020. Read the books:
- Clean Code by Robert C. Martin
- Clean Architecture by Robert C. Martin
- Agile Software Development by Robert C. Martin
I was hooked. The principles made so much sense:
- Single Responsibility
- Dependency Inversion
- Separation of Concerns
- Testability
But then I tried to apply it at work...
The Reality: Resistance to Change
Typical problems I faced:
- π’ "We've always done it this way"
- π° "New architecture? Too risky!"
- β° "We don't have time to refactor"
- π€· "Why change if it works?"
The structures were too entrenched. No trust in "new" architectures. The typical corporate fears.
Sound familiar?
The Solution: Build My Own Project
I realized: The best way to learn Clean Architecture is to build something real from scratch.
Not a TODO app. Not a toy example. A real-world library that solves a real problem.
So when I decided to build EDIFlow, I made a commitment:
- β Clean Architecture from Day 1
- β TDD (Test-Driven Development)
- β Agile principles (even solo!)
- β No compromises on code quality
Could I have hacked it together in a weekend? Sure!
But where's the learning in that? π€·
So... Was Clean Architecture Worth It?
This is the question everyone asks: "Is Clean Architecture worth the extra effort?"
My answer: YES! But it wasn't without challenges.
What went well:
- β 599 tests - Writing tests became easy (and fun!)
- β Zero coupling - Changed parser implementation twice, no problem
- β Added 4 EDIFACT versions - Clean separation made it trivial
- β Confidence - I can refactor without fear
But there were challenges too:
- β οΈ More files - Sometimes felt like overkill for simple features
- β οΈ Initial velocity - First weeks were slower ("I could have hacked this in a weekend!")
- β οΈ TypeScript DI complexity - No framework = manual wiring gets verbose
- β οΈ Solo discipline - Easy to cut corners when no one is watching
The verdict? For a library like EDIFlow: Absolutely worth it! Every hour spent on architecture saved me days in maintenance.
For a throwaway script? Probably overkill.
(We'll dive into the honest pros & cons, with real examples, in Part 5!)
3. Why TypeScript? π
EDI parsing is complex. You're dealing with:
- 618+ message types (ORDERS, INVOIC, DESADV...)
- Thousands of segment definitions
- Complex validation rules
- Delimiters, escape characters, special cases
Without type safety, this becomes a nightmare.
TypeScript Benefits for EDIFlow:
1. Type Safety for Complex Parsing Logic
// β JavaScript - Runtime errors waiting to happen
const delimiters = {
component: ':',
element: '+',
segment: "'"
};
delimiters.component = delimiters.element; // Oops! No error! π₯
// β
TypeScript - Caught at compile time
export class Delimiters {
private constructor(
public readonly component: string,
public readonly element: string,
public readonly segment: string
) {
if (component === element) {
throw new Error("Delimiters must be different!");
}
}
}
2. IntelliSense = Developer Happiness
// β
Auto-completion works!
const order = mapper.mapToBusinessObject(message);
console.log(order.documentNumber); // IntelliSense suggests fields
console.log(order.parties.buyer.id); // Type-safe navigation
console.log(order.lineItems[0].quantity); // No guessing!
3. Interface-Driven Design (Perfect for Clean Architecture!)
// Domain Layer - Just an interface, no implementation details
export interface IEDIParser {
parse(message: string): EDIMessage;
}
// Infrastructure Layer - Implements the interface
export class EdifactMessageParser implements IEDIParser {
parse(message: string): EDIMessage {
// EDIFACT-specific logic here
}
}
This is Dependency Inversion in action! The domain doesn't know about EDIFACT. The domain just knows "I need a parser."
4. Easy to Publish to npm
TypeScript compiles to JavaScript, so it works everywhere:
npm install @ediflow/core # Works in Node.js
import { EdifactParser } from '@ediflow/core'; # Works in browsers (with bundler)
Plus, TypeScript generates .d.ts files automaticallyβusers get IntelliSense out of the box!
5. Strong Ecosystem
- Vitest for testing (fast, great DX)
- tsup for building (zero config!)
- TypeScript strict mode catches bugs early
TypeScript Made EDI Development Enjoyable
Before EDIFlow, EDI development was:
- π« Debugging runtime errors
- π€· Guessing what
element[3]means - π₯ Breaking changes at runtime
With TypeScript:
- β Compile-time safety
- β IntelliSense everywhere
- β Refactoring with confidence
TypeScript isn't just a nice-to-have for EDIFlow. It's essential.
4. Why Open Source? π
Learning in Public
I could have built EDIFlow as a private project. But I chose open source for several reasons:
1. Accountability
When you know others might read your code, you write better code.
No shortcuts. No "I'll fix this later." Everything has to be production-ready.
2. Community Feedback
Open source means:
- π Bug reports from real users
- π‘ Feature suggestions I never thought of
- π€ Potential contributors
- π Documentation improvements
The best products are built WITH the community, not just FOR them.
3. Portfolio & Learning
Let's be honest: If I'm spending 100+ hours building this, I want to:
- β Show it in my portfolio
- β Get feedback from experts
- β Help others with the same problem
- β Build my personal brand
Open source is the ultimate resume.
4. Solving a Real Problem
I'm not the only one struggling with EDI libraries. By open-sourcing EDIFlow, I hope to:
- Help developers new to EDI
- Provide a modern alternative to legacy tools
- Show that EDI can be developer-friendly
5. MIT License = Maximum Freedom
EDIFlow is MIT licensed:
- β Use it commercially
- β Modify it however you want
- β No attribution required (but appreciated!)
- β No strings attached
Why MIT? Because I want maximum adoption. The more people use it, the better it gets.
5. What is EDIFlow? π
Okay, enough about motivation. What IS EDIFlow?
EDI = Electronic Data Interchange
Companies exchange business documents electronically:
- Purchase Orders (ORDERS)
- Invoices (INVOIC)
- Shipping Notices (DESADV)
- Inventory Reports (INVRPT)
Instead of paper, they send structured messages like:
UNH+1+ORDERS:D:96A:UN'
BGM+220+ORDER12345+9'
DTM+137:20240201:102'
...
EDIFACT = UN/EDIFACT Standard
EDIFACT (Electronic Data Interchange For Administration, Commerce and Transport) is the United Nations standard for EDI.
It's used globally, especially in:
- π’ Logistics & Supply Chain
- π Manufacturing
- π₯ Healthcare
- ποΈ Government
EDIFlow = Modern TypeScript Library for EDI
EDIFlow is:
- β Parser - EDIFACT string β TypeScript objects
- β Validator - 3-phase validation (Syntax β Structure β Business)
- β Builder - TypeScript objects β EDIFACT string
- β Mapper - Auto-convert to/from business objects
- β Schema Exporter - Generate JSON Schema & TypeScript types
Built with:
- Clean Architecture (Uncle Bob)
- TypeScript (strict mode)
- TDD (599 tests!)
- Zero dependencies (core package)
And this is just the beginning! π
Right now, EDIFlow supports EDIFACT (4 versions). But the journey continues:
- π X12 (ANSI ASC X12) - Coming soon!
- π More EDI formats - We're agile, we follow the flow!
- π Community-driven features - What does the community need?
The Clean Architecture foundation makes adding new formats easy. That's the power of good design!
Quick Example:
import { DIContainer } from '@ediflow/core';
// 1. Parse EDIFACT string
const container = DIContainer.getInstance();
const parseUseCase = container.resolve('ParseEDIUseCase');
const result = parseUseCase.execute({
message: edifactString,
standard: 'EDIFACT'
});
console.log(result.message.messageType); // "ORDERS"
// 2. Map to business object (type-safe!)
const mapper = container.resolve('BusinessObjectMapper');
const order = mapper.mapToBusinessObject(result.message);
console.log(order.documentNumber); // "ORDER12345"
console.log(order.parties.buyer.id); // "BUYER123"
console.log(order.lineItems[0].productId); // IntelliSense works!
// 3. Modify with type safety
order.lineItems[0].quantity = 150;
// 4. Build back to EDIFACT
const buildUseCase = container.resolve('BuildEDIUseCase');
const ediString = buildUseCase.execute({
message: mapper.mapFromBusinessObject(order),
standard: 'EDIFACT'
});
This is what "modern EDI" looks like. β¨
6. Project Stats π
Let me give you a sneak peek at what we've built so far:
Packages (npm)
Current (EDIFACT):
- @ediflow/core - Parser, Validator, Builder engine (MIT)
- @ediflow/edifact-d96a - D.96A (1996) - 89 messages (MIT)
- @ediflow/edifact-d01b - D.01B (2001) - 155 messages (MIT)
- @ediflow/edifact-d20b - D.20B (2020) - 178 messages (MIT)
- @ediflow/edifact-d12a - D.12A (2012) - 196 messages (MIT, Prep)
Coming Soon:
- @ediflow/x12 - ANSI ASC X12 support π
- More formats - We're agile, we follow where "Flow" leads us! π
Current Total: 618 EDIFACT message types supported (and growing!)
Tests & Quality
- β ~600 tests passing (unit + integration + e2e)
- β ~90% test coverage (goal: 95%+)
- β Clean Architecture - All layers tested independently
- β
TypeScript strict mode - No
anytypes! - β Zero dependencies (core package)
Architecture
βββββββββββββββββββββββββββββββββββββββββ
β Presentation Layer β CLI, API, UI (Future)
β β
β βββββββββββββββββββββββββββββββββββ β
β β Infrastructure Layer β β Parsers, Repositories
β β β β
β β βββββββββββββββββββββββββββββ β β
β β β Application Layer β β β Use Cases, Services
β β β β β β
β β β βββββββββββββββββββββββ β β β
β β β β Domain Layer β β β β Entities, Value Objects
β β β βββββββββββββββββββββββ β β β
β β βββββββββββββββββββββββββββββ β β
β βββββββββββββββββββββββββββββββββββ β
βββββββββββββββββββββββββββββββββββββββββ
Dependency direction: Always inward β β β β
Note: Presentation Layer (CLI, REST API, Web UI) is planned for future releases!
7. What's Coming in This Series? ποΈ
This is just Part 1 of 6! Here's what's next:
Part 1 (This Article): Why? β You are here! β
- Motivation & personal story
- Why Clean Architecture?
- Why TypeScript?
- Why Open Source?
Part 2 (Next Week): Domain Layer Deep-Dive
- Entities (EDIMessage, Segment)
- Value Objects (Delimiters, Standard, Version)
- Business Rules (ValidationRule, MandatoryRule)
- Real code examples from EDIFlow
Part 3: Application Layer - Use Cases & Services
- ParseEDIUseCase, ValidateMessageUseCase, BuildEDIUseCase
- ComposableValidationService
- DTOs & Dependency Injection
- How orchestration works
Part 4: Infrastructure Layer & Monorepo Structure
- Parsers (EdifactMessageParser)
- Repositories (FileBasedMessageStructureRepository)
- Why 5 packages? (Monorepo strategy)
- TypeScript project references
Part 5: Presentation Layer - The Interface
- CLI tools and commands
- REST API design (planned)
- Web UI vision (future)
- How Presentation Layer stays clean
- Dependency Injection from top to bottom
Part 6 (Finale): Lessons Learned & Future
- Was Clean Architecture worth it? (honest answer!)
- Performance analysis (benchmarks!)
- Testing insights (600 tests!)
- What I'd do differently
- Roadmap & future plans
Each article: 1000-1800 words, deep technical dive with real code!
8. Conclusion & Call to Action π
My Journey
EDIFlow is more than just a library. It's my journey of:
- π Learning Clean Architecture by doing, not just reading
- π Proving TypeScript is perfect for enterprise-grade libraries
- π Building in public and sharing the process
- π§ Making "old school EDI" developer-friendly
- π Following the Flow - Starting with EDIFACT, next X12, then... who knows? We're agile!
It's Not Perfect (Yet!)
I'm not claiming EDIFlow is perfect. I've made mistakes. I've refactored. I've learned.
And that's exactly what this series is about.
In the next 4 articles, I'll show you:
- β What worked (spoiler: a lot!)
- β What didn't work (also a lot!)
- π‘ How to apply Clean Architecture in TypeScript
- π Real code from a production-ready library
This is Pair Programming... with You!
I built EDIFlow with GitHub Copilot as my pair programming partner. Now I'm sharing the journey with you.
Follow along, and let's learn together!
π Links & Resources
Try EDIFlow:
- π¦ npm: @ediflow/core
- π GitHub: ediflow-lib/core
- π Documentation
Join the Community:
- π¬ Discord: EDIFlow Community - Real-time chat & support
- π£ GitHub Discussions
- π§ Email: hello.ediflow@gmail.com
Read More:
- π Clean Code by Robert C. Martin
- π Clean Architecture by Robert C. Martin
- π Agile Software Development by Robert C. Martin
π What Do YOU Want to Learn?
This series is for you. What topics should I cover?
- Domain Layer patterns?
- TypeScript DI without frameworks?
- Testing strategies?
- Performance optimization?
Comment below! π
π’ Next Up: Part 2 - Domain Layer
Next week, we'll dive into the Domain Layer:
- How do Entities differ from Value Objects?
- Why immutability matters
- Real code examples from EDIFlow
- TypeScript patterns that make Clean Architecture easier
See you next week! π
If you found this helpful:
- β Star EDIFlow on GitHub
- π¬ Join our Discord
- π Follow this series (click "Follow" on my Dev.to profile!)
- π Share with your network
Let's make EDI development great again! π
This article is part of the "Building EDIFlow: A Clean Architecture Journey in TypeScript" series. Follow along as we build a production-ready EDIFACT library from scratch using Clean Architecture principles.
Word Count: ~1,650 words
Reading Time: ~7 minutes
Series: Part 1 of 6
Coming Soon:
- Part 2: Domain Layer Deep-Dive
- Part 3: Application Layer
- Part 4: Infrastructure & Packages
- Part 5: Presentation Layer
- Part 6: Lessons Learned
Top comments (0)