I'm not really thrilled with Cloud Native Buildpacks.
They are optimized for the Heroku style use case of being able to create a "universal builder", which will detect and build projects of various types (node, python, go. java, etc).
The problem is that the buildpacks in such universal builders are pretty much black boxes to people trying to use them in projects, and often end up handling simple cases, but failing for more complex, or if flexible enough to handle most projects, ends up being rather arcane.
Of course, you can end up creating your own buildpacks for your company that do just what you need, but even then you may have some projects with really complex requirements. For such complex projects, you made need to create a special buildpack.
Lastly, buildpacks don't provide full flexibility in the output. For example, a minimal container for a program written in Go only needs a single layer with the resulting executable set as entrypoint. You can't make that with buildpacks. In practice most "stacks" will provide some full OS environment, like an apline or ubuntu image. On top of that is a mandatory runtime layer container the `/cnb/lifecycle/launcher` executable. Finally your buildpack outputs are layered on top of that.
(Admittedly there is work-in progress that would allow specifying some other base image via Dockerfile, and you could specify "FROM scratch". This would mean an empty base layer, on which the launcher layer, the config layer, app layer, which is a little better, but still not as nice as a fully customizable output.)
They are optimized for the Heroku style use case of being able to create a "universal builder", which will detect and build projects of various types (node, python, go. java, etc).
The problem is that the buildpacks in such universal builders are pretty much black boxes to people trying to use them in projects, and often end up handling simple cases, but failing for more complex, or if flexible enough to handle most projects, ends up being rather arcane.
Of course, you can end up creating your own buildpacks for your company that do just what you need, but even then you may have some projects with really complex requirements. For such complex projects, you made need to create a special buildpack.
Lastly, buildpacks don't provide full flexibility in the output. For example, a minimal container for a program written in Go only needs a single layer with the resulting executable set as entrypoint. You can't make that with buildpacks. In practice most "stacks" will provide some full OS environment, like an apline or ubuntu image. On top of that is a mandatory runtime layer container the `/cnb/lifecycle/launcher` executable. Finally your buildpack outputs are layered on top of that.
(Admittedly there is work-in progress that would allow specifying some other base image via Dockerfile, and you could specify "FROM scratch". This would mean an empty base layer, on which the launcher layer, the config layer, app layer, which is a little better, but still not as nice as a fully customizable output.)