Creating a Package With Hooks

I’ve written a nice little pattern I’d like to make available to the community as a package. Normally this wouldn’t be an issue, but this pattern requires a Hook/modifying the app.js.

Is there a preferred way of packaging hooks? Ideally so that no modification of a user’s JavaScript is necessary. It wouldn’t be too burdensome if the user had to do it manually, but it’d feel much more magical if this could be done by the package itself.

Would love any advice and references to other packages with this problem.


You have answered your own question. :slight_smile:

Yes, any magic is not recommend. Phoenix is often seen as a replacement for Rails, but it’s technically not a framework. That’s why any kind of magic is not recommend anywhere.

If it’s only a matter of adding one hook then it’s definitely not a problem. The question is what to do when you have let’s say 10+ hooks. Yeah, it may look bad just to export hooks, so I would recommend to export them anyway and add an optional setupHooks function ideally if it would have only and except support.

How about something like this one?

import {setupHooks, PhoneNumber} from "my_lib"
let Hooks = {}
/* user specific hooks goes here */
setupHooks(Hooks, {except: [PhoneNumber])
let liveSocket = new LiveSocket("/live", Socket, {hooks: Hooks, ...})

For me it looks clear enough as long as your project documentation would list all available JavaScript hooks + description of setupHooks function with examples.

1 Like

As your user is a developer, there’s no issue in having them top modify the JavaScript code to add a reference to your library. To make this as simple as possible, I followed the approach from Phoenix LiveView and extended it for LiveMotion with a JS library a user can import.

It does look something like this:

  1. From your JS, export a function to create your hooks (optionally taking some options or so - as Eiji said). live_motion/live_motion.ts at main · benvp/live_motion · GitHub
  2. Configure esbuild to build your JS files. live_motion/config.exs at main · benvp/live_motion · GitHub
  3. Define a build task in the mix.exs file for building the assets. live_motion/mix.exs at main · benvp/live_motion · GitHub
  4. Include the built assets in the repository and define a package.json in the root of your project. In that you define the module and main keys which point to your JS file. That’s so that can be imported from the other project via the file path in deps folder. You can see the instructions in the README

Hope that helps.


This will work, thanks!

Thanks @benlime - I stole your package format, works good. You can see the result here. I credited you in the README.

1 Like