
Urql: a GraphQL client library - smusumeche
https://formidable.com/blog/2019/urql-2019/
======
lewisl9029
I really like the simplicity of the core library and this approach of starting
from a simple core and building on top of it with the same primitive for
extensibility as the one you offer to users.

Apollo has also been moving in this direction with composable links, but in a
zig-zaggy way since it's still got some baggage from its days as a monolithic
library, and recent decisions to move local state management into core seems
to be backtracking from that effort somewhat, so it's great to see some
competition in this area that really approaches extensibility as a first class
citizen rather than an afterthought.

With that said, I'd love to see an officially supported normalizing cache
implementation as well, in addition to the simple document cache Urql
currently provides as a default:

[https://formidable.com/open-source/urql/docs/basics/#code-
cl...](https://formidable.com/open-source/urql/docs/basics/#code-
classlanguage-textcacheexchangecode)

Apollo and Relay's normalizing cache helps ensure a single source of truth for
every piece of server data, which is incredibly valuable for non-trivial apps
that have the same pieces of data fetched in multiple places that would
otherwise have to be manually kept in sync, which anyone who has ever tried to
do so can tell you is generally extremely tedious, error prone, and likely a
frequent contributor to user-facing bugs. That to me is by far the most
compelling value prop of GraphQL clients like Apollo and Relay. It'd be great
if I didn't have to choose between automatic normalization and a more flexible
extensibility model (fwiw, I'd choose the former).

~~~
philplckthun
Cheers! I'm happy to say that a normalising cache is indeed in progress and
we're planning to finish it soon
[https://github.com/kitten/urql](https://github.com/kitten/urql) exchange-
graphcache

We've got the cache itself done but are just figuring out the API for its
customisability in terms of cache resolvers and such

------
mxstbr
Have been playing around with urql on a project for a couple of months now,
mainly due to the small bundle size. Urql is 7.5kB min+gzip, where Apollo and
Relay add ~30kB min+gzip!

Great to see Formidable investing further in it, I am very excited to see
first class extensibility.

~~~
methyl
> Urql is 7.5kB min+gzip, where Apollo and Relay add ~30kB min+gzip!

How is that 22.5kB making any difference? Unless you are working on a project
that will be used on very slow connections I see no point in choosing a
library basing on such small difference in size. And if you really are
targeting those slow connections then maybe going SPA is not the best choice?

~~~
brianmathews
From recent bundle audits of e-commerce sites built with React, less than 20%
of the code was actual custom site code and the remaining 80% was from
dependencies.

If the bundle size is 550kb min/gzipped, that's 110kb of app code, and 440kb
of dependencies. Some of the largest dependencies in a recent audit were:
moment (60kb), swiper (32kb), lodash (24kb), react-select (26kb), raven.js
(12kb), polyfills (25kb), mobile-detect (15kb), and then a bunch of smaller
dependencies that made up the remaining 300kb.

Using this performance budget calculator you can quickly see how each 25kb of
JS adds ~.3s to your TTI on a mobile phone:

[https://perf-budget-calculator.firebaseapp.com/](https://perf-budget-
calculator.firebaseapp.com/)

If developers shop around for smaller alternatives of each dependency, then
they can cut their load times pretty drastically.

~~~
underwater
Fixating on package size alone is missing the forest for the trees. A good
library can massively reduce your application size and pay for itself many
times over.

For example, Relay removes the need for a lot of Flux and network request
boilerplate. Going beyond that, it can collapse serial network fetches down
into one request, massively speeding up page loads.

(This doesn't apply to moment, that library is just designed in a brain dead
way).

------
patrickaljord
There is also the new GraphQL integration into mobx-state-tree that was just
announced last week by the author of mobx, you can check it here
[https://github.com/mobxjs/mst-gql](https://github.com/mobxjs/mst-gql)

~~~
yodon
> this project closes the gap between GraphQL and mobx-state-tree as state
> management solutions. GraphQL is very transport oriented, while MST is great
> for client side state management. GraphQL clients like apollo do support
> some form of client-side state, but that is still quite cumbersome compared
> to the full model driven power unlocked by MST, where local actions,
> reactive views, and MobX optimized rendering model be used.

MST and GraphQL together does sound like a pretty serious win

~~~
patrickaljord
It is pretty cool indeed, you can watch his presentation of the project here
[https://www.youtube.com/watch?v=Sq2M00vghqY](https://www.youtube.com/watch?v=Sq2M00vghqY)
(disclosure, I organize this conf).

------
xiaomai
GraphQL is amazing. Building an API and then playing around with it in
GraphiQl is really a exciting experience.

I've played with Relay (relay-modern looks great, but when I needed to pick a
graphql client it hadn't been released yet). Apollo is frustrating: it's big
and complicated and obsessed with stuff that I don't want (link-state and a
bunch of product up-sells).

I'm glad urql is getting some more attention and I'll definitely give it a
spin.

~~~
jayd16
What is GraphQL like in production at scale? It seems like a neat concept but
how do traditional web technologies like edge caching work?

~~~
dalore
It tips it all on it's head. It's generally a POST request and so doesn't
cache at alls (you can configure it with a long GET request). All caching is
done client side but at object level, including not requesting fields that you
might have already requested previously on other calls.

------
scyclow
urql's great, and the maintainers are super helpful and friendly. I've been
using it on a project for a couple months now. Very straightforward and plays
well with TypeScript. My one criticism is that it doesn't quite do enough in
some cases, but I haven't spent the time to learn much about exchanges. As the
ecosystem grows, I see this problem going away.

~~~
huy-nguyen
I’m also interested in exploring exchanges.

------
yodon
Excited to see some competition for Apollo. Apollo may do lots of things but
exactly what and why and how remains a mystery to me. Apollo just feels
needlessly large, opaque, and inadequately documented to me. Reading about
urql, the combination of minimalist architecture with first class support for
React hooks sounds like just what I'd been hoping would emerge.

~~~
peggyrayzis
Hi from Apollo! We appreciate your honest feedback. Part of my team (Developer
Experience) is responsible for our documentation. What features are
inadequately documented? We'd like to fix that for you if we can.

~~~
yodon
The issue is not that there is a simple feature that's inadequately
documented. It's that I have no high level understanding of what all the
pieces are and how they fit together. Tell me exactly what I'm getting from
Apollo that I don't get from fetch. Tell me what caching does, when, how, and
how to invalidate it. Tell me about links and middleware. This is a very
complex batteries included technology. I don't even feel like I understand
where the batteries go, much less what they are doing for me, I'm just copying
and pasting code that others have used into my projects and hoping I have
about the right amount of stuff included.

Your customer didn't write all the Apollo code. The docs feel like they are
written with the assumption that we understand the architecture and goals as
well as you do and we just want to do some simple task with it to get started.
I fear however that this is fundamentally not a docs problem. It feels like a
problem where the Apollo devs didn't start by asking "how can I build
something that will be easy for 3rd party devs to use and understand", they
started with "oooh that would be cool". Urql feels like it started with a very
simple and clear conceptual foundation that provides a clear roadmap for how
and where more complex features get attached.

If you can reduce Apollo down to a clear and simple framework in the docs that
actually covers everything that it does, then you're golden. I suspect however
that the underlying architectural simplicity that would be required for you to
do this doesn't actually exist. If it does, you face a docs problem, if it
doesn't, then docs are just a bandaid.

~~~
true_religion
You can’t invalidate the cache in Apollo. You have to clear all items, or
update a specific part to a new value.

It’s not a simple key value cache, but a graph of values, which makes
invalidation more complex but still in my opinion that is a huge oversight.

Hopefully an Apollo dev can give us some insight here: why is the cache a
requirement? Why is it threaded into every bit of code? I’ve seen so many bugs
from the cache, and I know there is a technical reason it has to be part of
the core codebase, but I have forgotten why.

~~~
peggyrayzis
The normalized cache is the one of the main value props of Apollo Client. It
optimizes reads, automatically updates queries without a refetch for some
mutations, supports optimistic updates, and can also return partial data for
large queries. If you don't need a cache, then you can use fetch, graphql-
request, or even Apollo Link to fire off a simple GraphQL request. You also
don't have to use our cache implementation (apollo-cache-inmemory) with Apollo
Client. There are other implementations that make different tradeoffs.

For what it's worth, we are rearchitecting parts of the cache to support
invalidation and garbage collection for Apollo Client 3.0. The only reason why
we don't have it yet is because it's a tough problem to solve - one mutation
could invalidate an infinite amount of queries. We're committed to solving
this soon though because we know the community really wants it.

------
leetbulb
I _really like_ the implementation with hooks. I experimented with a similar
pattern on top of Apollo on a side project. Going to play with urql today!
Thank you!

------
alexrage
This is refreshing upon first glance. The Apollo Client docs are such a mess.

~~~
peggyrayzis
Hi from Apollo! My team (Developer Experience) is responsible for making sure
you can find what you need in the docs. What improvements would you like to
see?

~~~
alexrage
A more consistent documentation experience. A lot of code examples import
various modules, but those modules have no documentation. For example: Docs >
Client > Apollo Link mentions `graphql-tools` and schema stitching, with a
link to read more. Clicking that link takes you to a page that says it's
deprecated, and then links to a blog post about why.

Another example: Is `apollo-link-state` deprecated? The docs for `apollo-link-
state` don't mention that, but the Local state management page in Apollo
Client sure says it is.

~~~
WorldMaker
Similar to the deprecation issue, a number of Links still say "under active
development" or similar pre-release "warnings" in their GitHub READMEs but
that isn't reflected in the documentation site, making it tough to figure out
what is considered stable and what isn't without jumping back and forth
between GitHub and the documentation site, and there's still questions of
whether or not perhaps the README warnings are stale. It would also maybe be
great to have something of a roadmap of when those links might be considered
"production ready" especially if the documentation site is already
recommending them as project solutions.

The example to mind is last time I was trying to do something (a few months
back) `apollo-link-rest` was highly recommended in the documentation as a
potential solution, but yet visiting the GitHub for it seemed to be saying the
exact opposite that it wasn't ready yet and was filled with massive API shifts
and bugs/issues to iron out before "production ready".

~~~
alexrage
Indeed. It boils down to having no trust in the documentation because of the
conflicting messages.

------
lprd
Excited to try this out! Also glad to see Apollo getting some more
competition. I made a side project last year with the Apollo ecosystem, it
confused the hell out of me.

------
revskill
Most of graphql client library is non-lazy on url part. In my apps, i use a
lazy apollo client API interface though:

const data = useQuery(url, graphql_query, variables)

The point here is that, the ApolloClient is lazily constructed and reused only
when the hook is called.

I don't know why Graphql must be used with non-lazy url instead.

More than that, you don't need a Provider, because the apollo-client is reused
between the calls.

------
nicwolff
Fun, I don't know Typescript (and barely remember JavaScript!) but maybe I'll
try to add automatic persisted queries compatible with the apollo-link syntax
[https://github.com/apollographql/apollo-link-persisted-
queri...](https://github.com/apollographql/apollo-link-persisted-
queries#protocol)

------
danpalmer
We use Urql and are loving it at Thread. Nice and lightweight, easy to use,
easy to build our own infrastructure around.

------
mikeyhew
Does it typecheck queries for you based on the schema, and generate a response
type for TypeScript?

~~~
smusumeche
No, but you can do something like this:
[https://formidable.com/blog/2019/strong-
typing/](https://formidable.com/blog/2019/strong-typing/)

~~~
mikeyhew
Oh cool, they have a package for urql: [https://graphql-code-
generator.com/docs/plugins/typescript-u...](https://graphql-code-
generator.com/docs/plugins/typescript-urql)

I might try it out once it supports the new hooks.

------
kodon
are you supposed to say urql like "Urkel"?

~~~
thom_nic
I clicked the article link just because I was expecting to see this guy:
[https://en.wikipedia.org/wiki/Steve_Urkel#/media/File:Steve_...](https://en.wikipedia.org/wiki/Steve_Urkel#/media/File:Steve_Urkel.jpg)

------
holtalanm
really interesting, but i took a look at the docs, and they 100% look like
urql is only compatible with react. Can I use urql with Vue.js, or would I
just be inviting misery upon myself if i tried?

~~~
fernandotakai
we've been using apollo with vue.js (and typescript!) with a django-graphene
backend and we've been having zero problems.

honestly, it's my favorite stack nowadays.

------
ludwigvan
This library is also quite minimal:
[https://github.com/f/graphql.js](https://github.com/f/graphql.js)

------
holtalanm
their Exchange architecture reminds me of the Plug framework used by Phoenix
on Elixir.

------
cobaimelan
They also support abort fetch request :) :) :)

------
mc5ive
Glorious

