React vs Solid vs Svelte

Hypothesis

React is bad

What else can we use?

Plain HTML and CSS

Plain HTML and CSS

SolidJS

  1. TSX
  2. Signals
  3. Control Flow Components
  4. Stores
  5. Compilation

1. TSX

export const Modal: Component<Properties> = (properties) => {
 let dialogReference: HTMLDialogElement | undefined;

 const answer = createSignal(42)

 createEffect(() => {
  const emoji = properties.emoji();

  if (dialogReference === undefined || emoji === undefined) {
   return;
  }

  dialogReference.showModal();
 });

 return (
  <Show when={properties.emoji() !== undefined}>
   <dialog ref={dialogReference}>
    <Emoji emoji={properties.emoji()!} disableSelection={true} />

    <p>And the correct answer is: {answer()}</p>

    <div class={styles.buttons}>
     <Button onClick={properties.onSelection}>Add to Selection</Button>

     <Button onClick={properties.onClose}>CLose</Button>
    </div>
   </dialog>
  </Show>
 );
};
  1. TSX
  2. Signals
  3. Control Flow Components
  4. Stores
  5. Compilation
  • Backbone of reactivity
  • Use proxies
  • No callbacks
  • createSignal
  • createEffect

3. Control Flow Components

<For each={state.list} fallback={<div>Loading...</div>}>
  {(item) => <div>{item}</div>}
</For>

<Show when={state.count > 0} fallback={<div>Loading...</div>}>
  <div>My Content</div>
</Show>

<Switch fallback={<div>Not Found</div>}>
  <Match when={state.route === "home"}>
    <Home />
  </Match>
  <Match when={state.route === "settings"}>
    <Settings />
  </Match>
</Switch>
  1. TSX
  2. Signals
  3. Control Flow Components
  4. Stores
  5. Compilation
  • One big signal
  • Do not need context
  • Not as extensive as Redux
  1. TSX
  2. Signals
  3. Control Flow Components
  4. Stores
  5. Compilation
  • constructor, notrender
  • Does not need optimized libraries
  • Smaller footprint

Svelte

  1. Syntax
  2. Reactive Statements (Runes)
  3. Logic Blocks
  4. Stores
  5. Compilation

1. Syntax

<script lang="ts">
  import { type Emoji as EmojiType } from '../api';
  import Button from './Button.svelte';
  import Emoji from './Emoji.svelte';

  export let emoji: EmojiType | undefined;
  export let onClose: () => void;
  export let onSelection: () => void;

  let dialog: HTMLDialogElement | undefined;

  $: emoji !== undefined && dialog?.showModal();
</script>

{#if emoji !== undefined}
  <dialog bind:this={dialog}>
    <Emoji {emoji} disableSelection={true} />

    <div class="buttons">
      <Button on:click={onSelection}>Add to Selection</Button>

      <Button on:click={onClose}>Close</Button>
    </div>
  </dialog>
{/if}

<style>
...
</style>
  1. Syntax
  2. Reactive Statements (Runes)
  3. Logic Blocks
  4. Stores
  5. Compilation
  • The magic word$
  • Just declaring and updating variables
  • Event dispatching

3. Logic Blocks

{#each array as item}
    <p>{item}</p>
{/end}

{#if suitcase}
    <p>We happy</p>
{:else question}
    <p>42</p>
{\end}

{#await expression}...{:then name}...{:catch name}...{/await}

{#key expression}...{/key}
  1. Syntax
  2. Reactive Statements (Runes)
  3. Logic Blocks
  4. Stores
  5. Compilation
  • writable, readable, readonly, derived
  • No context needed
  • set, update and subscribe
  • Needs $inside a component
  1. Syntax
  2. Reactive Statements (Runes)
  3. Logic Blocks
  4. Stores
  5. Compilation
  • No need for optimized library
  • Slightly larger bundle than Solid
  • Imperfect TS support

Conclusion

It's Fun to Experiment

Svelte Is Really Good

Questions?