Elm es conocido por su modelo funcional puro, su tipado fuerte y la ausencia de errores en tiempo de ejecución.
Pero históricamente ha tenido una gran limitación: no puede ejecutarse en el backend.
Ahí entra Lamdera, un lenguaje derivado de Elm que propone algo ambicioso:
“Desarrollar aplicaciones fullstack en Elm, con estado compartido entre cliente y servidor, sin escribir ni una línea de JavaScript ni HTTP.”
Lamdera es un lenguaje y un entorno de ejecución creado por James Carlson, completamente compatible con Elm, pero que agrega:
- Servidor integrado (no hace falta backend separado)
- Comunicación automática cliente-servidor
- Persistencia de estado
- Despliegue con un solo comando
En otras palabras, Lamdera hace que Elm sea fullstack.
El compilador transforma tu código en una aplicación que corre tanto del lado del cliente como del servidor, sin necesidad de gestionar APIs, JSON o sincronización manual.
Lamdera extiende The Elm Architecture (TEA), pero con dos bucles de actualización:
uno en el cliente y otro en el servidor.
Ambos comparten el mismo modelo (Model) y el mismo tipo de mensaje (Msg), por lo que el tipado es consistente en toda la aplicación.
Un proyecto Lamdera se organiza con tres módulos principales:
- Main.elm
- Client.elm
- Server.elm
module Main exposing (..)
import Lamdera exposing (ClientProgram)
import Shared exposing (..)
import Client
import Server
main : ClientProgram Shared.Model Shared.Msg Shared.ToServer Shared.ToClient
main =
Lamdera.client
{ init = Client.init
, update = Client.update
, view = Client.view
, subscriptions = Client.subscriptions
, onServerMsg = Client.onServerMsg
, onClientConnect = Client.onClientConnect
, onClientDisconnect = Client.onClientDisconnect
}
Contiene los tipos comunes:
module Shared exposing (..)
type alias Model =
{ counter : Int }
type Msg
= Increment
| Decrement
type ToServer
= SaveCounter Int
type ToClient
= CounterUpdated Int
Client.elm : Maneja la vista y la interacción del usuario:
module Client exposing (..)
import Lamdera exposing (sendToServer)
import Element exposing (..)
import Shared exposing (..)
init : (Model, Cmd Msg)
init =
({ counter = 0 }, Cmd.none)
update : Msg -> Model -> (Model, Cmd Msg)
update msg model =
case msg of
Increment ->
let
new = model.counter + 1
in
( { model | counter = new }
, sendToServer (SaveCounter new)
)
Decrement ->
let
new = model.counter - 1
in
( { model | counter = new }
, sendToServer (SaveCounter new)
)
Server.elm: Contiene la lógica del servidor (persistencia, validación, etc.):
module Server exposing (..)
import Lamdera exposing (sendToClient)
import Shared exposing (..)
update : ToServer -> Model -> (Model, Cmd Msg)
update msg model =
case msg of
SaveCounter value ->
( { model | counter = value }
, sendToClient (CounterUpdated value)
)
Con esto ya tenés una aplicación fullstack con comunicación cliente-servidor y estado sincronizado, todo en Elm.
Lamdera incluye herramientas propias:
- lamdera run → ejecuta el servidor local y abre el navegador
- lamdera check → analiza tipos y compilación
- lamdera deploy → compila, sube y publica tu app
- Dashboard online → permite gestionar el estado y logs
Lamdera todavía no es software libre (su runtime es cerrado, aunque gratuito para uso educativo y hobby).
Tampoco permite acceso directo a archivos o bases de datos externas (aunque se planea extender esto).
Aun así, su estabilidad es sorprendente: muchas aplicaciones en producción usan Lamdera desde hace años sin un solo error en runtime.
Lamdera lleva la promesa de Elm un paso más allá:
> “Sin errores, sin JavaScript, y ahora… sin backend.”
Con él, podés crear aplicaciones reactivas, tipadas y persistentes con una única base de código funcional pura.
Ideal para quienes aman Elm y quieren llevar sus principios hasta el servidor.
Dejo link: https://lamdera.com

