Am I missing something, or are custom plugins unnecessarily complicated?

Apologies if this comes across as critical. I’ve only recently started using Baserow, and I’ve been very impressed with it so far. It’s a great tool, and I’m very happy it exists.

However, I recently skimmed the documentation and sample plugins with the idea of making a custom plugin to add a formula function to my baserow install, and I’m left feeling like this process is far more complicated than it should be.

Say I want to create a new formula function like this:

tocaps("my string") >> "MY STRING"

I would expect that such a plugin could potentially be as simple as the following two files:

# plugin.ts

export default {
  name: "My Plugin",
  functions: "./functions.ts"

# functions.ts

export function tocaps(input: string): string {
  return input.toUpperCase();

(I only used TypeScript in my example since that’s the language I’m most comfortable in. I don’t actually care what language plugins are written in.)

However, from my limited understanding of how Baserow custom plugins are expected to be built, such a plugin would require many more directories, files, and configurations to achieve the same basic result.

Am I correct in saying this? I’m really hoping I’m wrong here.

Anyway, my strong preference for a Baserow plugin architecture would that it be as thin and unopinionated as possible. Provide some basic entrypoints for the plugin developer to hook into, and then let the developer decide how complicated or simple they want to make their plugin architecture based on the problem they’re trying to solve. I think taking this approach would both make it far easier for people new to Baserow to learn how to build plugins, and simultaneously make it much easier to build a wide variety of powerful plugins without wrestling with Baserow’s assumptions.

Again, I’m currently very impressed with Baserow, but ran into this today and wanted to share my thoughts in the hopes that I’m wrong about how simple a plugin can be, or that my perspective might have some influence on the future direction the team takes with plugin support.

Hi @narthur,

Thank you for your feedback. I completely understand your perspective and agree that a good plugin architecture should be as minimalistic and unopinionated as possible.

However, our current architecture necessitates the implementation of both the backend in Python (Django) and the frontend in JavaScript (Vue.js/Nuxt.js) for a custom plugin. While we strive to achieve a thinner and less opinionated architecture, we’re not there yet.

For example, our formula language is a language shared between the frontend and the backend. The frontend requires the knowledge of the syntax to ensure that the formula is correct in terms of syntax, while in the backend, the formula is transformed into an SQL query after parsing and sanitization. This is done to achieve the fastest possible processing of all rows of the table(s)

This has the benefit of being very fast when updating large volumes of data running a SQL query, but the downside is that a simple formula requires both the definition in the front end and the actual implementation in the back end.

This explanation is not meant to sound like a justification for the fact that creating a plugin seems more complicated than necessary, but rather an example of a deliberate compromise we’ve made in favor of ensuring performance, even with large volumes of data, at the expense of a system that is very easy to extend but would not be able to guarantee the same performance with large datasets.

1 Like

I appreciate the extra context here. It makes sense that you can’t allow plugin developers to just do whatever they want since you need to compile to SQL for performance reasons. Super useful to understand.

I’m sure you all are way ahead of me on all this, but just thinking, what if the API was more like this?

export function myPlugin(context: PluginContext) {

It seems like you might be able to then use a single function provided by the plugin developer to both compile to SQL and also infer the front end typing.

Just a vague idea at the moment. Maybe later I’ll try working it through with a plausible use case to see if it still seems to make sense.