Skip to content

Conversation

@khajavi
Copy link
Member

@khajavi khajavi commented Nov 14, 2025

No description provided.

@netlify
Copy link

netlify bot commented Nov 14, 2025

Deploy Preview for zio-http ready!

Name Link
🔨 Latest commit ff0d8a2
🔍 Latest deploy log https://app.netlify.com/projects/zio-http/deploys/69176ce13c372600081e20da
😎 Deploy Preview https://deploy-preview-3790--zio-http.netlify.app
📱 Preview on mobile
Toggle QR Code...

QR Code

Use your smartphone camera to open QR code link.

To edit notification comments on pull requests, go to your Netlify project configuration.

title: Integration of Datastar with ZIO HTTP
---

[Datastar](https://data-star.dev/) is a hypermedia-driven framework for building reactive web applications using Server-Sent Events (SSE) and minimal JavaScript. The `zio-http-datastar-sdk` integrates Datastar with ZIO HTTP, bringing these capabilities to the ZIO ecosystem and allowing developers to create server-driven UIs with minimal frontend complexity.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That is not factual. It is not only using SSE. It can handle html (and json) responses too.


## Datastar Overview

Datastar uses declarative `data-*` HTML attributes to define reactive behavior, while the server streams updates via Server-Sent Events. The framework centers on signals, reactive variables prefixed with `$` (like `$username`, `$count`) that automatically synchronize between frontend and backend.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There is no auto syncro for signals. The user has to take care of it.


Datastar uses declarative `data-*` HTML attributes to define reactive behavior, while the server streams updates via Server-Sent Events. The framework centers on signals, reactive variables prefixed with `$` (like `$username`, `$count`) that automatically synchronize between frontend and backend.

For example, when a user types into an input field bound with `data-bind:email`, the `$email` signal updates locally and gets transmitted to the server with subsequent requests. The server can then push signal updates back using JSON Merge Patch (RFC 7396), or send HTML fragments that morph into the DOM. This bidirectional flow happens over SSE connections, which unlike traditional AJAX polling, maintain long-lived HTTP responses that can stream multiple events efficiently.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Here you actually say it correctly. The server can push signals.
Also there is no bidirectional flow via SSE. SSE is push from the server. In d* we just send requests. Answers might be text/html, SSE as a response or SSE event on a earlier established connection. That is up to the user. SSE connections might also be short lived

libraryDependencies += "dev.zio" %% "zio-http-datastar-sdk" % "@VERSION@"
```

You also have to include the Datastar JavaScript client module in your HTML pages. You can do this by adding the following script tag to your HTML head:
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I will add some helpers to create this scripts. I can adjust the docs in a later PR

```scala mdoc:compile-only
span(
dataSignals(Signal[String]("currentTime")) := js"",
dataText := Js("$currentTime"),
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The way it is designed is, to have

val $currentTime = Signal[String]("currentTime")
span(
  dataSignals($currentTime),
  dataText := $currentTime,
  ...

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

With the explicit recommendation, to let signal variables start with a $ so it is clear what they are.
Also this enables code navigation to see where the signal is used through the code. Please adjust this everywhere


The server can extract the signals from the request like this:

```scala mdoc:silent
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this not the same example like in line 60?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not the same, it uses the signal coming from the client.

val message = "Hello, world!"
ZIO.foreachDiscard(message.indices) { i =>
for {
_ <- ServerSentEventGenerator.executeScript("console.log('Sending character index: ' + " + i + ");")
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

prefer js interpolator in docs for js code

The server responds with a single-shot event that updates a greeting message with the provided username:

```scala mdoc:compile-only
Method.GET / "greet" -> handler { (req: Request) =>
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This should not be the recommended way. created this issue for it #3792

}

val route =
Method.GET / "hello-world" -> events {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we should in general push the endpoint API more. I would like to have the basic Datastar examples with Endpoint API instead.

khajavi and others added 4 commits November 14, 2025 16:18
Co-authored-by: Nabil Abdel-Hafeez <7283535+987Nabil@users.noreply.github.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants