Skip to main content

Serverless

Build custom plugins in any language with a free VM.

Written by Ryan Kulp
Updated over a week ago

We welcome advanced community plugins. But sometimes they require authors to host or maintain their own middleman services.

Using TRMNL Serverless you can achieve the flexibility of 3rd party tools (e.g. Cloudflare Workers) without spinning up services or paying for subscriptions.


Requirements

This feature is in private beta. Fill out this form or email [email protected] for access.

Quickstart

  1. Visit Plugins > Private Plugins > New, provide a name and click Save

  2. Click Edit Markup, then click the Serverless tab

  3. Select a programming language and build whatever you want*

*network access is included!

Code provided in the Serverless text editor must include a run function that returns a hash / dictionary / JSON friendly object. For example...

Ruby

Includes httparty gem for network requests. Must require in your code.

require 'httparty'

def quotes
HTTParty.get('https://dummyjson.com/quotes?limit=10')['quotes']
end

def run(input)
{ input:, quotes: }
end

Node

Includes fetch() module for network requests.

async function run(input) {
const res = await fetch("https://dummyjson.com/quotes?limit=1");
const data = await res.json();
return { quote: data.quotes[0] };
}


PHP
Includes standard curl extension for network requests.​

function run($input) {
$ch = curl_init("https://dummyjson.com/quotes?limit=1");
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$data = json_decode(curl_exec($ch), true);
unset($ch);
return ["quote" => $data["quotes"][0]];
}


Python

Includes Requests library for network request. Must import in your code.

import requests

def run(input):
data = requests.get("https://dummyjson.com/quotes?limit=1").json()
return {"quote": data["quotes"][0]}

Accessing existing variables

Global variables like {{ trmnl }} , as well as custom form field values, are available inside the parameter of your run function. We suggest input but it may be whatever you prefer.

Frequently Asked Questions

Can I refactor my existing (published) plugins to use this feature?

Please don't, at least not until April 2026. Because this feature is in private beta, downstream installations won't have access to the runtime.

Can I install additional packages into this VM?

Yes, but it's currently a manual process. Send us a live chat or email [email protected] with a particular package / gem / library you might need, and we can add it to the default image for your preferred language. For example, the Ruby image already has HTTParty included for simple network requests.

What are the specs on this runtime?

You get 128mb and 5 seconds to do your business.

Troubleshooting

We strongly encourage you to enable Debug Logs from your private plugin settings page while developing Serverless plugins. This will return native errors, for example:

let data = await fetch('https://dummyjson.com/quotes?limit=5')                     
^^^^^
SyntaxError: await is only valid in async functions and the top level bodies of modules
Did this answer your question?