docs: improve remote functions page
Nobody has claimed this yet.
- Dominant language
- JavaScript
- Stars
- 20.8k
- Forks
- 2.3k
- Avg merge
- 1d 16h
- Merged PRs (30d)
- 156
Description
Describe the problem
I'd love to improve remote functions docs, but wanted to get input before opening a PR.
Happy to split into separate issues if preferred.
1. Use blog for prerender, news/social for everything else
The /blog examples use db.sql inside query, but blogs in practice read from a CMS or flat files — not a database on every request. The blog is a natural fit for prerender and should stay there.
For query, form, command, and single-flight mutations, a social networking service (e.g. Reddit, Facebook) is a better fit: user-generated content is clearly dynamic, DB-backed, and naturally requires authentication — which also addresses the following issue.
Function names (getPosts, getPost, createPost) can stay the same, keeping the diff minimal:
| Domain | Section |
|---|---|
/blog |
prerender |
/sns |
query, form, command, single-flight |
2. Mention authentication in the Overview
The docs mention HTTP endpoints and validation, but never authentication. By the time readers reach the form example with auth.getUser(), they may have already written unprotected queries. I've seen this happen with LLM-assisted coding.
3. getPosts() === getPosts() is incorrect
This evaluates to false in both server and browser on @sveltejs/kit@2.61.0.
Queries are cached while they're on the page, meaning
getPosts() === getPosts().
The Deduplication section says "Multiple identical invocations of a query all point to the same instance", which suggests === identity is the design intent — meaning this is likely a wording issue. Either way, the note should be replaced with a plain-language explanation:
await getPosts({ limit: 10, offset: 10 });
await getPosts({ offset: 10, limit: 10 }); // points to same cache
await getPosts({ offset: 10, limit: 10 }).refresh(); // refreshes both
4. No-parameter list queries are unrealistic
getPosts() without arguments doesn't reflect real usage — lists always need pagination to avoid loading unbounded rows. A query without parameters makes sense when the result is a single item scoped to the current user, such as getAuthorStats() or getProfile().
getAuthorStats() would also fit the single-flight mutation example more naturally: creating a post should update the user's post count, which is a clearer refresh trigger than re-fetching the entire post list.
5. "the server handler knows what client data needs to be updated" is misleading
In most circumstances, the server handler knows what client data needs to be updated based on its arguments
This reads as if detection is automatic. The developer must explicitly call void getPosts().refresh() inside the handler. The sentence should clarify that the developer must explicitly specify what to update.
Also undocumented: if getPosts().refresh() is called server-side but no matching client instance is active, the behavior is unspecified. Presumably a no-op, but this should be stated explicitly.
6. limit in requested() means max batch size for query.batch
The appropriate limit value depends on how requested() interacts with the underlying query type:
- For a regular
query, each entry inrequested()triggers a separate DB/API call.limitcaps how many you'll accept, so it should be small. - For a
query.batchfunction, all requested refreshes are collected into a single batched call.limithere expresses the maximum batch size — the number of items the DB query receives — not the number of DB calls. It can and should be much higher.
7. Undocumented failure behavior in requested()/updates()
- If the client calls
submit().updates(getPosts)but the server handler never callsrequested(getPosts, N), the docs say "you need to accept them from the server as well" — implying the request is silently ignored, but this isn't stated explicitly. - If the number of client-requested refreshes exceeds the
limitpassed torequested(), the docs say they "will fail" without clarifying what that means — does the affected query enter an error state, is it silently skipped, or does the entire submission fail?
8. void vs await inconsistency in requested() examples
it's safe to throw away the promise from
refresh
If refresh() can be safely discarded because the framework awaits it automatically, should refreshAll() also be void? Or does refreshAll() behave differently and require explicit awaiting?
// Refresh `getPosts()` on the server, and send
// the data back with the result of `createPost`
// it's safe to throw away the promise from `refresh`,
// as the framework awaits it for us before serving the response
void getPosts().refresh();
// this is the same as looping over the result and calling `void query.refresh()`.
await requested(getPosts, 1).refreshAll();
Describe the proposed solution
See above
Alternatives considered
No response
Importance
nice to have
Additional Information
No response
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start with the remote functions documentation page, reading its Overview, Deduplication, query/form/command, and requested/updates sections. Review each of the eight proposed changes and confirm the intended wording and examples with maintainers, especially the undocumented failure behavior and refresh semantics. Done means the page accurately explains authentication, caching, pagination, refresh targets, batching limits, failures, and promise handling.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- javascript
- Domain
- documentation
- Issue type
- Documentation
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Active
- Clarity
- Mostly clear
- Newbie friendliness
- 50/100