Skip to the content

Reference

Limits of version 0

The parts of the specifications that the compiler of version 0 does not have yet.This page as Markdown
The specs describe the language that Surface will have. The compiler of version 0 does not have all of it yet. This page lists each gap and each limit of version 0 on one page. The specs mark the same gaps with "Not in version 0".Two private enums of two child components can have the same name in one file. tone={.warm} works for both. A longer expression, such as tone={a ? .warm : .cold}, finds only the first enum. Use another name, or export the enum.

1. Features that are compile errors

The compiler rejects these features with an error. The message of most errors ends with "is not supported in version 0".
Feature
Spec
What to do in version 0
Canvas and PlatformView
9.6, component reference 4.16, ADR-0089
Version 1 does not have them. For a drawing, use a Drawing with shapes (component reference 4.11).
transform, fill-rule="evenodd", gradients, text and use in an SVG file of an icon
component reference 4.12
Convert the file first, for example with svgo and its convertTransform plugin.
A user component, text or a block element in a Drawing
component reference 4.11
Put the shapes into the Drawing itself, and text above it in a Stack.
A utility that is not paint on a shape or a Group, for example rotate-45 on a Circle
component reference 4.11, ADR-0120
A shape has no box, so the native targets cannot apply these utilities. Change the coordinates of the shape, or put the transform on the Drawing.
More than 31 props and states in a component, 30 in a component with #fill, or more than 31 effects
7.4, 7.5
The web target keeps the dirty bits in 32-bit integers, so each target has this limit. A motion counts as a state (ADR-0104), and Window counts as a state in a component that reads it (ADR-0106). Move a group of values into a record, or a part of the markup into a component.
A record or an enum that holds a value of its own type outside a List or a Map
4.6
A native build gives each field a fixed size. Use children: List<Node> in place of next: Node?.
A fixed element without a place on both axes
layout spec 5.7, ADR-0106
A browser keeps the place in the flow, and a native target has no such place. Add top- or bottom-, and inset-s-, inset-e-, left- or right-, or inset-.
A box utility, a computed value, a variant form or an event on a Span
component reference 4.4a, ADR-0111
A Span takes only the utilities of text, and hover: and dark: with them. Put a part with padding, a border or a transform outside the Text, for example in a Row.
A name with __
3.1, ADR-0115
The compiler makes its own names with __. A JSON key with __, for example __typename, cannot be a field, and Json.decode ignores it.

2. Features that behave differently in version 0

Feature
Spec
What version 0 does
A fallback block that sends events
13.3
Not in version 0: a fallback block has only the functions of the module.
The theme while the app runs
layout spec 2.1
Theme.setMode chooses a variant of the theme (ADR-0072, ADR-0103), and Theme.setToken changes a color or a length (ADR-0082, ADR-0130). The title bar of a native window follows the system.
Animation
layout spec 5.10, ADR-0104
transition cannot animate a filter.
A spring in Safari before 17.2
layout spec 5.10, ADR-0104
That browser has no linear(). A spring in a rule uses a cubic-bezier of a similar shape, and a move uses ease-out. The enter of a Transition with a spring plays no animation.
An app in a view of a host
ADR-0041
surf build --target desktop --embed works on macOS only.
An Image on the native targets
component reference 4.5
Windows shows the first frame of an animated WebP. The cache is in memory only. A picture needs room in a texture of 4096 × 4096 device px: a larger one does not paint fully. A picture above 2^26 pixels does not paint, also after its scale (ADR-0109).
Text in other languages
ADR-0066
Chinese and Japanese lines break, Arabic and Hebrew paragraphs take their direction, and dir and lang work on all targets. Vertical text is not done. The selection of a mixed line is one rectangle.
Italic text on the native targets
ADR-0068, ADR-0131
The system font and the monospaced system font use the italic face of the platform. A variable font uses its axis. Another font gets a slant of 14 degrees. A theme cannot name a second file for italic.
An error boundary
language spec 9.5
#try has no retry. It catches the mount and the updates of its body, not event handlers, effects or tasks. A page from a server has no test of it yet.
A missing asset
component reference 4.5
The compiler checks a path in quotes. A computed path has no check: on the native targets, the image then paints nothing.

3. Checks that version 0 does not do

Check
Spec
What version 0 does
A utility that has no effect on its element, for example gap-1 on a Text or text-20 on an Image
layout spec 12
The compiler checks the name and the value of each utility, but not the element. surf lint finds the common cases (rule no-effect). Its list of rules is short, so it can miss a case.

4. Targets

Target
State
Web
Works, also with server rendering and hydration (SurfWave).
macOS
Works.
Linux
Works on Wayland. --x11 adds an X11 window with fewer features (ADR-0088).
Windows
Works on x86_64. CI builds the aarch64 binary and checks its size, but no test runs on an ARM device yet (W10). A surf from a checkout builds the binary with rust-lld and no Visual Studio (ADR-0136). CI runs the TodoMVC source and the mail client on Windows. surf package writes a signed MSIX package (ADR-0141). A release of surf for Windows and a signature for the public are not done (windows.md).
iOS and Android
Not done.
The web and the native targets have small differences. A separate page lists them.

5. A server

Limit
What to do in version 0
A server has no Rust crates, so it has no database client
Put the database behind an API, and set API_ORIGIN.
A server is a binary with a port
No serverless host and no Workers. Use a container or a machine.
A press before the script runs
It does nothing. A link and a form work with no script.
A server has no TLS
Put a proxy in front of it, and set ORIGIN. See security.
A server has no https: client
Http on the server takes http: only. Keep the API in your own network.
A server does not read a body in chunks
The answer is status 501. A proxy must send a length.
A server has no limit for each client
Let the proxy limit the rate and the connections of each client.
href and action take four schemes
A relative URL, http, https, mailto and tel. The element gets no attribute for another scheme (ADR-0109).

6. Tools

Limit
What to do in version 0
The releases of surf cover Linux x86-64 and macOS arm64
On another system, build surf from a checkout. This needs Rust 1.99 or later.
The Linux release of surf comes from Debian 12, so it needs glibc 2.36 or later
On an older system, build surf from a checkout. The apps that surf builds keep the minimum of the target matrix (PLAN.md section 12.3).
The first native build needs the network, and a native build needs a linker
Run surf doctor. It names the package of the linker. ADR-0101 gives the reason.
The host of --embed is a Rust crate, so it has its own Rust install
Only this case needs Rust. An app and its extern modules use the private toolchain.
surf test runs the native layout, not the CSS of the web
Test the web output with Playwright against a build.
A test that calls an extern module needs a host function or a fallback block
Give the module a fallback block.
A package has .surf files and extern files only
The app keeps the assets and the theme.
There is no central registry of packages
A git address or a path names a package.
surf dev answers only 127.0.0.1, localhost and [::1] on its own port (ADR-0109)
To try a page on another device, serve a build with another server.
The inspector only shows values (ADR-0105)
It cannot change a state. A derived value shows only after the app computed it. The paths under /__inspector/ belong to the inspector, so an app with routes cannot use them.
surf mcp --http has no TLS, no sign-in and no limit for each client (ADR-0107)
Put a reverse proxy in front of it. The proxy gives TLS and the rate limit of each client.

7. Decided for version 1, not built yet

On 2026-11-04, the project owner decided section 13 of the layout spec and section 18 of the language spec (ADR-0124 to ADR-0135). On 2026-11-05, the project owner answered the open questions for version 1 (ADR-0104, ADR-0109, ADR-0113, ADR-0124, ADR-0126, ADR-0134 and ADR-0139 to ADR-0141). On the same day, the project owner decided the motion of version 1 (ADR-0150 to ADR-0154). On the same day, ADR-0155 to ADR-0159 gave the media of P6.25. The specs describe these features, but the compiler of version 0 does not have them yet. Version 0 gives a compile error for the new syntax, or it does what the last column says.
Feature
Spec
What to do in version 0
The other fixes of the native differences
ADR-0131
docs/native-differences.md lists each row with the plan "1.0".
A module constant gets its value at its first read, with one value for the process on a server
language spec 7.3, ADR-0131
The web computes it at the load, and a server has one value for each thread.
The base path for a picture of src/assets on a page below the root of an app with routes
wave spec 5, ADR-0139
A path such as assets/logo.png reads its file relative to the address of the page. Show such a picture only on the root page, or give it a full URL.
The base path for a Link, a form and an Http request of a web app with no routes
wave spec 5, ADR-0139
Only the script and the stylesheet get the base path. Write the prefix into each address that starts with /.
The split of a Span into parts, the underline and the line through of the parts of a split text, and a computed opacity- on a split text on the web
layout spec 5.10, ADR-0153
Split the whole Text. Give the opacity with a fixed opacity- or with an animation.
The hidden pointer, and the Tab key and the accessibility tree only in the video and its bar, in the full screen of a Video
component reference 4.5d, ADR-0156, decision 29
The video and its bar cover the window. A native window goes into the full screen mode of the system.
The full screen mode of the window of the X11 fallback of Linux
component reference 4.5d, ADR-0156, decision 27
The video and its bar cover the window. The window keeps its size.
The pause of a video that autoplay started while no part of it is in the window
component reference 4.5b, ADR-0158, decision 4
Give the Video bind:paused, and pause it in on:visible.
object- utilities on a Video with controls
component reference 4.5b, 4.5d
The bar has the style of the element, and its video fits with object-contain.
The Track elements of a block in the menu of the captions
component reference 4.5d, ADR-0157, decision 9
Write each Track outside a block.
The tags <i> and <u> of a text cue on the native targets
component reference 4.5c, ADR-0157, decision 5
The text shows without the italic and the underline. <b> works.
indent- (text-indent) on the native targets
layout spec 5.9, 12, ADR-0160
The web indents the first line. The native targets have no indent. Put the first word of the text into a Span with a margin, or use a Row.
Function types in extern modules come after version 1 (ADR-0133). Percentages in calc() and subgrid also come after version 1 (ADR-0125, ADR-0126).