I would like to make use of a external library to parse the core domain entities. Doing this in a naive way it would look like the following:

import { z } from 'zod';

const Audience = z.object({
  name: z.string(),
  id: z.string(),

type Audience = z.infer<typeof Audience>;

const buildMakeAudience = ({ getShortId }: { getShortId: () => string }) => {
  return (input: Audience) => {

    const { id, name } = Audience.parse(input);

    return Object.freeze({
      getId: () => id || getShortId(),
      getName: () => name,

export { buildMakeAudience };

However this breaks the dependency rule and our entities now depend on the 3rd party lib directly. I am interested to know if it is possible to use a 3rd party lib when defining the schema and types of your core domain entities, or if its best to just validate them by hand?

I could of course inject the parse() method, but to me this still feels heavily coupled to the external lib.


1 Answer 1


Clean architecture / onion architecture is not about avoiding dependencies on third party libraries. It's about being mindful of which components depend on what, and generally practicing dependency inversion so that external interfaces depend on your core business logic, not your core business logic on external components like a database layer.

Validation is typically part of your core business logic: it should not be possible to create an entity in an invalid state. How you implement this is up to you. If a third party library makes it easier to perform validation, using it sounds pretty sensible. A Zod schema is not like a database schema in that it would create a dependency on an external system, it is more like a way to conveniently handle Data Transfer Objects. And in order to achieve dependency inversion, the DTOs must be defined by the inner core/layer in an onion architecture, here your core business logic.

  • Thanks, would you mind providing a more concrete example?
    – dendog
    Dec 13, 2021 at 9:13
  • @dendog Example of what? Your code example seems fine.
    – amon
    Dec 13, 2021 at 15:11
  • Ok well your answer is very high level, it makes sense but does not give any insight into actual implementation. My code breaks the clean rules, as I import a lib into the entity.
    – dendog
    Dec 14, 2021 at 9:44
  • 1
    @dendog Your code isn't violating the Dependency Rule. Your entities just use a library to define validation rules instead of doing everything manually (see also this related question). Also, in general, I'd suggest not following Robert C Martin's recommendations too closely. He's prone to hyperbole and has limited experience with long-term software maintenance. His ideas often point you in the right direction but it's easy to accidentally take them too far.
    – amon
    Dec 14, 2021 at 11:34

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.