Live data from Hacker News

Show HN: FP-pack – Functional pipelines in TypeScript without monads

github.com

1–10 of 17 posts

Show HN: FP-pack – Functional pipelines in TypeScript without monads

#1
Hi HN,

I built fp-pack, a small TypeScript functional utility library focused on pipe-first composition.

The goal is to keep pipelines simple and readable, while still supporting early exits and side effects — without introducing monads like Option or Either.

Most code uses plain pipe/pipeAsync. For the few cases that need early termination, fp-pack provides a SideEffect-based pipeline that short-circuits safely.

I also wrote an “AI agent skills” document to help LLMs generate consistent fp-pack-style code.

Feedback, criticism, or questions are very welcome.

Show HN: FP-pack – Functional pipelines in TypeScript without monads
github.com

Re: Show HN: FP-pack – Functional pipelines in TypeScript without monads

#4
While I like the concept, the side-effect pattern might be difficult for the average developer to understand (without fp-pack knowledge) in a shared codebase:

https://github.com/superlucky84/fp-pack?tab=readme-ov-file#s...

Still, this approach is very useful for most business logic, too bad most programming languages don't provide a nice syntax for this.

Re: Show HN: FP-pack – Functional pipelines in TypeScript without monads

#6

One thing I’d especially like feedback on is the SideEffect approach. It’s intentionally not a monad, and I’m curious how others feel about this trade-off compared to Option/Either in real-world TypeScript codebases.

Is early termination the only supported side effect? Its name suggests a more general capability, but I didn't see more examples in my (cursory) look at the readme

Re: Show HN: FP-pack – Functional pipelines in TypeScript without monads

#7
post #3

How is this not a monad? It might be trying really hard not to reify the core concept of a monad, but it seems to me like it ends up being essentially a complicated monad.

It’s definitely monad-adjacent.

The main difference is that SideEffect isn’t a compositional context — there’s no bind/flatMap, and composition intentionally stops once it appears. It’s meant as an explicit early-exit signal in pipe-first code, not a general computation container.

Re: Show HN: FP-pack – Functional pipelines in TypeScript without monads

#8
post #4

While I like the concept, the side-effect pattern might be difficult for the average developer to understand (without fp-pack knowledge) in a shared codebase: https://github.com/superlucky84/fp-pack?tab=readme-ov-file#s... Still, this approach is very useful for most business logic, too bad most programming languages don't provide a nice syntax for this.

That’s a fair point, and I agree.

The SideEffect pattern is intentionally explicit, so without fp-pack context it can look unfamiliar at first. The trade-off is making early exits visible in the code, rather than hiding them in conditionals or exceptions.

In practice, most code stays in plain pipe/pipeAsync. SideEffect is meant for a small number of boundary cases only.

And I agree — better language-level syntax for this kind of pattern would make it much easier to adopt.

Re: Show HN: FP-pack – Functional pipelines in TypeScript without monads

#9
post #5

The default any return type from pipelines is kind of brutal. Seems like a real footgun. Is that fixable?

That’s a fair point — it can definitely become a footgun if you’re not careful.

This happens because `runPipeResult` defaults its generic parameter to `R = any`. When type safety matters, the intended solution is to use `pipeSideEffectStrict`, which preserves all possible SideEffect result types as a precise union throughout the pipeline.

The default version prioritizes ergonomics and simplicity, while the strict version prioritizes type safety.

Also, fp-pack is still in an early stage, so the usability and API choices haven’t been fully validated yet. That’s why feedback like this is especially helpful in shaping the direction of the library.

Re: Show HN: FP-pack – Functional pipelines in TypeScript without monads

#10
post #6

One thing I’d especially like feedback on is the SideEffect approach. It’s intentionally not a monad, and I’m curious how others feel about this trade-off compared to Option/Either in real-world TypeScript codebases.

Is early termination the only supported side effect? Its name suggests a more general capability, but I didn't see more examples in my (cursory) look at the readme

Good question.

Early termination is the most common use case, but it’s not the only thing SideEffect represents. The name is intentionally a bit broader — it’s meant to model “effects where normal composition should stop”.

In practice, that includes things like validation failures, logging or notifications at pipeline boundaries, and error reporting or metrics. That said, the scope is deliberately conservative.

SideEffect isn’t meant to be a general-purpose effect system. If it were, it would quickly turn into something very close to a monad or effect framework, which I’m intentionally avoiding.

Post reply on HN