Poll: Should Typst Print Engine Support Live in Frappe Core or Stay App-Level?

For context, this comes from work on Crispy Print, an independent Typst-based print/document publishing app for Frappe:

I want to be clear that this poll is not asking whether the whole Crispy Print app should be merged into Frappe core.

Frappe currently relies mainly on HTML-based print formats rendered through wkhtmltopdf or browser/chrome-based PDF generation.

I have been experimenting with Typst as a document-oriented print engine for invoices, reports, and formal business documents. Typst gives stronger pagination, layout control, font handling, and deterministic PDF output compared with HTML-to-PDF workflows.

Crispy Print includes many app-level features: a visual builder, Typst blocks, branding profiles, report templates, regulatory workflows, preview tooling, and other higher-level document publishing features. Those may make more sense as an independent app.

The question here is narrower:

Where should the architectural boundary be drawn?

Should Frappe core provide first-class support for Typst as a print/PDF engine, similar to wkhtmltopdf and chrome, while advanced authoring tools remain in apps?

Or should Typst support remain entirely app-level, with no core changes?

I am looking for feedback on the engine boundary, not a judgment on the full Crispy Print feature set.

What contribution path makes the most sense?

  • Add Typst engine support to Frappe core
  • Keep Typst entirely as an independent app feature
  • Hybrid: improve Frappe engine hooks/core support, keep builders and advanced features app-level
  • Not needed right now
0 voters

Curious whatā€˜s @revant_one’s plans/opinions are for Framework M!

I’ve PrintProtocol and there are 2 default implementations that come with standard package:

  • Jinja2->HTML (no wkhtmltopdf, just render html and send to browser to do whatever)
  • gotenberg adapter that uses https://gotenberg.dev/

To keep the code modular developers can maintain their app (pip install framework-m-typst)
with TypstAdapter. Or if it’s truly needed in standard adapters then they can add it with lazy imports so there’s no dependecy bloat in standard.

E.g. here is ability to use temporal.io workflow without adding temporal dependecy in standard:

libs/framework-m-standard/src/framework_m_standard/adapters/workflow/temporal_adapter.py Ā· main Ā· castlecraft / framework-m Ā· GitLab this method lazy imports temporal.

I’ve Sacred CI, if it’s not green, it’s not good to be merged! Hygiene is maintained by strict QA. If you pass that your code is good.

My take in general:

  • buy over make: frappe loves to build tools from scratch. I prefer to piggyback on other larger communities.
  • core must be extendible. Adding or replacing any dependency in frappe means copy-pasting large part of code. I prefer Modular composition.
  • Frappe trusts the developer and not the code. I trust the code, not the developer. Show me you can pass my CI and I’ll respect your code.
  • part of my ci is signing CLA that bots cannot do!
  • most stuff is out of syllabus for frappe framework.
3 Likes

I read your reply at 05:00 in the morning, local time.

I thought I have messed up big time. I figured I have a long day to address your reply.

I opened the reply again after I had my tea, and realized it is about your own framework and @ahassoun in a brief sentence might be suggesting Typst as a print engine for your framework.

Thanks for stopping by.

I’d appreciate it if you take a look at Crispy Print, when your time allows, and give any feedback.

1 Like

Steps:

  • I went through your hooks.py did not find any print related hooks.
  • Does frappe have print related hooks? I found Hooks, mentions on_print_pdf
  • I searched frappe source code for on_print_pdf and found it in print_utils.py. It is called when get_print is called.

It seems frappe does not let you hook print engine. This is a feature you can send to Frappe, ā€œhookable print engineā€.

  • Keep the your app separate, develop it to solve your problem.
  • Send the hook-ability PR to frappe. Open a branch and create issue showcasing the branch.
  • If PR is accepted you make your app implement the hook and reduce the code from your app.
  • If PR is not accepted, you have already solved your problem in your app.

Thanks for the checkup.

You’re absolutely right, there is no Frappe print engine related hook.

  • print_utils.py hardcodes wkhtmltopdf and chrome as accepted values for pdf_generator.
  • I’ve submitted a feature request sometime ago.

Why did I request feedback:

  • I can’t use Frappe’s native print menu/icon item.
  • The use of frappe.ui.form.on(ā€˜*’, …) is not supported, I would guess for security reasons, so I used IIEF to introduce the typst print button to doctypes. The logic is a bit messy. Currently it looks for doctypes that have a crispy format set as default to display the typst button in the form.
  • I used IIEF in crispy_print_button.js to circumvente Frappe/ERPNext restrictions.

Thanks for the feedback.

1 Like