DocsPlaygroundBlogCommunity
  • Playground
  • Blog
  • Community
  • X
  • Bluesky
  • GitHub
  • Forum
Language ManualAPISyntax LookupReact
Overview
  • Introduction
  • Installation
  • Migrate from JSX v3
Main Concepts
  • Elements & JSX
  • Rendering Elements
  • Components and Props
  • Arrays and Keys
  • Events
  • Refs and the DOM
  • Context
  • memo
  • Styling
  • Router
  • Lazy Components
  • Import / Export ReactJS
  • Server Components
    • Server Functions
    • Server Components
    • Client Components
Hooks & State Management
  • Hooks & State Management Overview
  • useEffect Hook
  • useState Hook
  • useReducer Hook
  • useContext Hook
  • useRef Hook
  • Build A Custom Hook
Guides
  • Beyond JSX
  • Forwarding Refs
  • Extensions of props
Extra
  • LLMs
Docs / rescript-react / Server Components
Edit

Server Components

ReScript allows you to create server components as described in React 19.

Server Functions

To mark a file exposing functions as Server Functions,
you can use the @@directive("'use server'") tag.

ReScriptJS Output
// src/actions/MyActions.res
@@directive("'use server'")

let myHelper = () => "Hello from the server!"

let helloWorld = async () => {
  let response = myHelper()
  response
}

Warning: It is recommended to use an interface file here, to ensure only the functions you want to expose are exposed.

RES
// src/actions/MyActions.resi let helloWorld: unit => Promise<string>

myHelper will remain unexported with this change.

Server Components

Server components can be async.

ReScriptJS Output
// src/pages/Index.res
let data = [1, 2, 3]
let getData = () => Promise.resolve(data)

@react.component
let make = async () => {
  // fetch some data from somewhere
  let data = await getData()
  <html>
    <body>
      <h1> {React.string("Hello from server component")} </h1>
      <ul>
        {data->Array.map(id => <li> {React.int(id)} </li>)->React.array}
      </ul>
    </body>
  </html>
}

// Export as default
let default = make

A server function can be inlined in a server component and passed as prop to a client component.

ReScriptJS Output
module ClientComp = {
  @react.component @module("some-module")
  external make: (~submit: int => promise<bool>) => React.element =
    "SomeClientComp"
}

let data = [1, 2, 3]
let getData = () => Promise.resolve(data)

@react.component
let make = async () => {
  let data = await getData()

  let addData =
    @directive("'use server'")
    async (id: int) => {
      // add to data store
      data->Array.push(id)
      true
    }
  <html>
    <body>
      <h1> {React.string("Hello from server component")} </h1>
      <ul>
        {data->Array.map(id => <li> {React.int(id)} </li>)->React.array}
      </ul>
      <ClientComp submit={addData} />
    </body>
  </html>
}

Note that when decorating the function with @directive("'use server'"), we use a single @, where to annotate an entire file we use @@directive("'use server'").

Client Components

Client components should use the @@directive("'use client'") attribute.

ReScriptJS Output
// src/components/ClientComp.res
@@directive("'use client'")

@react.component
let make = (~submit) => <button> {React.string("yow from client")} </button>
Import / Export ReactJSHooks & State Management Overview

© 2025 The ReScript Project

About
  • Community
  • ReScript Association
Find us on