Skip to main content

Getting Started

So you want to try Server Defined Rendering with Rise Tools? Lets go!

when you have no idea what you're doing

Quick Start Server Dev

Fist we will create a server that controls UI for our app.

Start by cloning the server quickstart repo:

git clone git@github.com:rise-tools/rise-server-quickstart.git

This starter includes the following:

The main code is in src/index.tsx:

import { createWSServer, state, view } from '@rise-tools/server'
import { YStack, Text, Button } from '@rise-tools/kitchen-sink/server'

const [count, setCount] = state(0)

const incrementer = view(get => (
<YStack>
<Text>The count is {get(count)}</Text>
<Button onPress={() => {
setCount(c => c + 1)
}}>
Plus 1
</Button>
</YStack>
))

console.log('Starting server on ws://localhost:8888')

createWSServer({ incrementer }, 8888)

This code establishes:

  • An internal state model, just a simple integer
  • A view model which renders a YStack container,
    • Text which displays the current count
    • Button with a handler that mutates the internal count state
  • The WebSocket server on port 8888 which serves the incrementer view

To run the app:

cd rise-server-quickstart
npm install
npm run dev

If everything goes well, your server is ready to use and develop on!

Playground App

The fastest way to start developing is by downloading the Rise Playground App from the App Store or Play Store.

Connect to your server by adding ws://<your-computer-ip>:8888 and setting the path to incrementer

React Native Quick Start

Or you can connect a React Native app to your new server. We will demonstrate in a fresh Expo app. Start by cloning the mobile quickstart repo:

git clone git@github.com:rise-tools/rise-mobile-quickstart.git

This starter app has the following setup:

See src/riseComponents.ts which defines the local component library for the app:

import {
FormComponents,
LucideIconsComponents,
QRCodeComponents,
RiseComponents,
SVGComponents,
TamaguiComponents,
} from "@rise-tools/kitchen-sink";

export const components = {
...FormComponents,
...LucideIconsComponents,
...QRCodeComponents,
...RiseComponents,
...SVGComponents,
...TamaguiComponents,
};

Next, look at src/modelSource.ts which defines the connection to the WebSocket server we created earlier:

import { createWSModelSource } from "@rise-tools/ws-client";

export const modelSource = createWSModelSource("ws://localhost:8888");

Finally lets see how it all ties together in the home screen app/index.tsx:

import { Rise } from '@rise-tools/react'
import {
useHapticsActions,
useLinkingActions,
useToastActions,
} from '@rise-tools/kitchen-sink'
import { modelSource } from '@/src/modelSource';
import { components } from '@/src/riseComponents';

export default function HomeScreen() {
return (
<Rise
modelSource={modelSource}
components={components}
path="incrementer"
actions={{
...useHapticsActions(),
...useLinkingActions(),
...useToastActions(),
}}
/>
);
}

Here we render the main <Rise> component, we specify the component library and model source, and we specify the incrementer path to reference the model on the server which provides our UI. We also include the actions from the kit, so the server can perform certain local behaviors such as haptics and linking.

Time to Code on the Server!

At this point you should be able to change the code in index.tsx and see the UI reflect your changes in the app.

TODO: example code changes

Next Steps

  • Navigation
  • Custom Components
  • ???