JavaScript - Frameworks and Libraries
Next.js
-
<script>&&& ping bong !!!</script> -
Built on React.
Component-based Frameworks
-
Almost all frontend frameworks are syntax/ergonomic sugar on top of native JS and the browser.
-
None add fundamentally new runtime capabilities that the browser can’t already do.
-
.
-
No JS framework suddenly gives threads, parallel execution, or new DOM APIs.
-
They cannot extend what the browser can do.
-
Why frameworks exist :
-
They reduce repetitive wiring for large apps.
-
They integrate state, DOM updates, and async requests in a structured way.
-
They handle edge cases (race conditions, lifecycle, error states, component reuse) that become messy in raw JS.
-
Automate common patterns
-
Reduce bugs and boilerplate
-
Provide a declarative programming model
-
Comparisons
-
Reactivity : React/Preact use component-level state and rerender subtree. Solid uses signals; updates are localized. Qwik uses signals/refs but focuses on serializing and lazy event handlers.
-
Rendering : React/Preact VDOM diff. Solid direct DOM ops (compiled). Qwik renders on server then resumes only what’s needed.
-
Hydration : React/Preact full or partial hydration. Solid partial hydration techniques. Qwik aims for no traditional hydration — it resumes.
-
Bundle/runtime : Preact < React (smaller). Solid small runtime for reactivity. Qwik pushes logic to server/serialized payload; runtime focuses on resuming.
-
Use case : React/Preact good for heavy interactivity and library ecosystem. Solid for maximum update performance. Qwik for extreme lazy-load and fast TTFP.
Vanilla JS (Not a framework, I'm just comparing)
Characteristics
-
AJAX:
-
fetch()orXMLHttpRequest(older API).
-
-
Problems appear as you scale:
-
Multiple endpoints → repeated fetch calls.
-
Multiple components updating DOM → repeated
innerHTMLupdates. -
Error handling → repeated try/catch blocks.
-
State management → you must track which component has which data.
-
UI updates tied to async → manually coordinate loading states, spinners, etc.
-
Examples
-
More complex async behavior :
const widgets = [ { id: "widget1", url: "/data1" }, { id: "widget2", url: "/data2" }, { id: "widget3", url: "/data3" }, ]; const status = document.getElementById("status"); let completed = 0; widgets.forEach(w => { const el = document.getElementById(w.id); el.innerHTML = "Loading..."; fetch(w.url) .then(res => { if (!res.ok) throw new Error("Network error"); return res.text(); }) .then(html => { el.innerHTML = html; }) .catch(err => { el.innerHTML = "Error loading widget"; console.error(err); }) .finally(() => { completed++; if (completed === widgets.length) { status.innerHTML = "Dashboard loaded"; } }); });
Svelte
-
-
No Virtual DOM.
-
Works as a compiler, to turn the
.sveltecode into plain JS. -
Full TypeScript support (
.sveltefiles with<script lang="ts">) -
Compile-time type checking on props, stores, and events
-
1 component per file.
-
Every
.sveltefile has 3 parts:-
script + markup + style.
-
-
Very fast runtime, small bundle
-
AJAX:
-
Fetch or
loadfunctions use AJAX under the hood.
-
Examples
-
Button increases a counter :
<script>
let count = 0;
const increment = () => count++;
</script>
<p>Count: {count}</p>
<button on:click={increment}>Increment</button>
-
Ex2 :
<script>
export let items = [];
</script>
{#if items.length}
<ul>
{#each items as item}
<li>{item.title}</li>
{/each}
</ul>
{:else}
<div>No items</div>
{/if}
Qwik
-
.
Solid
-
No Virtual DOM.
-
Similar to React.
-
Uses JSX.
-
Kinda like React, but with a Svelte-like compiler
-
"A more well thought-out and faster version of React".
Examples
-
Button increases a counter :
import { createSignal } from 'https://cdn.skypack.dev/solid-js';
import { render } from 'https://cdn.skypack.dev/solid-js/web';
function Counter() {
const [count, setCount] = createSignal(0);
return (
<div>
<p>Count: {count()}</p>
<button onClick={() => setCount(count() + 1)}>Increment</button>
</div>
);
}
render(() => <Counter >, document.getElementById('app'));
-
Ex2 :
import { For, Show } from "solid-js";
export default function List(props) {
return (
<Show when={props.items.length} fallback={<div>No items</div>}>
<ul>
<For each={props.items}>{item => <li>{item.title}</li>}</For>
</ul>
</Show>
);
}
import { For } from "solid-js";
export default function Users(props) {
return <ul><For each={props.users}>{u => <li>{u.name}</li>}</For></ul>;
}
Vue
-
-
React's components, Angular's templates.
-
A
.vuefile is:-
Template + Script + Style
-
Characteristics
-
Has Virtual DOM.
-
AJAX:
-
Vue itself doesn’t do AJAX, but most Vue apps use it for components.
-
Examples
-
Button increases a counter :
<div id="app">
<p>Count: {{ count }}</p>
<button @click="increment">Increment</button>
</div>
<script type="module">
import { createApp, ref } from 'https://unpkg.com/vue@3/dist/vue.esm-browser.js';
const App = {
setup() {
const count = ref(0);
const increment = () => count.value++;
return { count, increment };
}
};
createApp(App).mount('#app');
</script>
-
Ex2 :
<template>
<div>
<ul v-if="items.length">
<li v-for="item in items" :key="item.id">{{ item.title }}</li>
</ul>
<div v-else>No items</div>
</div>
</template>
<script setup>
defineProps({ items: Array });
</script>
Preact
-
React-compatible API, smaller runtime.
-
Has Virtual DOM.
-
Uses JSX.
Examples
-
Button increases a counter :
import { h, render } from 'https://unpkg.com/preact@latest?module';
import { useState } from 'https://unpkg.com/preact@latest/hooks/dist/hooks.mjs?module';
function Counter() {
const [count, setCount] = useState(0);
return (
<div>
<p>Count: {count}</p>
<button onClick={() => setCount(count + 1)}>Increment</button>
</div>
);
}
render(<Counter >, document.getElementById('app'));
React
-
From Facebook, 2013.
-
Uses JSX.
-
Has Virtual DOM.
-
Svelte or Solid sounds much better than this thing.
-
AJAX:
-
Via
fetch, Axios, or libraries like React Query; client-side rendering is driven by async data.
-
Asynchronous Behavior
-
React doesn’t fundamentally change how concurrency works—JS is still single-threaded—but it improves ergonomics and state management around asynchronous operations
-
React doesn’t add new concurrency primitives—it doesn’t give JS threads, parallelism, or async I/O that didn’t exist.
-
Everything React does is built on native JS: Promises, the event loop,
fetch, timers, etc. -
Automatic DOM diffing → no manual
innerHTMLmanipulation.-
Your component re-renders automatically when state changes.
-
In Vanilla JS :
fetch("/data") .then(res => res.text()) .then(html => document.getElementById("widget").innerHTML = html);-
You must track which element corresponds to which data.
-
Any additional async operations updating the same element require careful coordination.
-
-
In React :
const [data, setData] = useState(null); useEffect(() => { fetch("/data") .then(res => res.text()) .then(setData); }, []); return <div>{data || "Loading..."}</div>;-
React automatically re-renders the component when state changes.
-
No manual DOM manipulation.
-
Concurrency conflicts are minimized because state updates are batched and applied in order.
-
-
Examples
-
Button increases a counter :
import { useState } from "react";
import { createRoot } from "react-dom/client";
function Counter() {
const [count, setCount] = useState(0);
return (
<div>
<p>Count: {count}</p>
<button onClick={() => setCount(count + 1)}>Increment</button>
</div>
);
}
const root = createRoot(document.getElementById("app"));
root.render(<Counter >);
-
Simple async behavior :
function Component() {
const [data, setData] = React.useState(null);
React.useEffect(() => {
fetch("/data")
.then(res => res.json())
.then(setData);
}, []);
return <div>{data}</div>;
}
-
More complex async behavior :
function Dashboard() { const [widgets, setWidgets] = React.useState([]); const [loaded, setLoaded] = React.useState(false); React.useEffect(() => { Promise.all([ fetch("/data1").then(r => r.text()), fetch("/data2").then(r => r.text()), fetch("/data3").then(r => r.text()), ]) .then(results => setWidgets(results)) .finally(() => setLoaded(true)); }, []); return ( <div> {widgets.map((w, i) => ( <div key={i}>{w || "Loading..."}</div> ))} {loaded && <div>Dashboard loaded</div>} </div> ); }
Angular
-
Google, 2010.
-
Angular 2 in 2016.
-
Requires TS.
Characteristics
-
Has Virtual DOM.
-
Reactivity model: Change detection.
-
AJAX:
-
Has built-in
HttpClientfor AJAX requests; components update via async data.
-
-
Template syntax, but bound tightly to TypeScript logic.
// user-list.component.ts
import { Component } from '@angular/core';
@Component({
selector: 'user-list',
template: `
<ul>
<li *ngFor="let u of users">{{ u.name }}</li>
</ul>
`
})
export class UserListComponent {
users = [{ id:1, name:'Alice' }, { id:2, name:'Bob' }];
}
Examples
-
Button increases a counter :
// counter.component.ts
import { Component } from '@angular/core';
@Component({
selector: 'app-counter',
template: `
<p>Count: {{ count }}</p>
<button (click)="increment()">Increment</button>
`
})
export class CounterComponent {
count = 0;
increment() { this.count++; }
}
// app.module.ts
import { NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { CounterComponent } from './counter.component';
@NgModule({
declarations: [CounterComponent],
imports: [BrowserModule],
bootstrap: [CounterComponent]
})
export class AppModule {}
Backbone
Ember
-
-
Convention over configuration.
Lit
-
Google.
-
Focused on Web Components.
Stencil
-
Focused on Web Components.
Mithril
-
Virtual DOM.
Libraries
HTMX
-
HTMX .
Alpine.js / Alpine AJAX
-
Popular replacement of JQuery.
Alphine AJAX
<div x-data>
<button x-on:click="$ajax.get('/users').then(html => $refs.list.innerHTML = html)">
Load Users
</button>
<div x-ref="list"></div>
</div>
Alphine.js
<div x-data="{ open: false }">
<button @click="open = !open">Toggle</button>
<p x-show="open">Now visible</p>
</div>
JQuery
Characteristics
-
AJAX:
-
.ajax(),.get(),.post()provide AJAX out of the box.
$.get("/data", function(html) { $("#result").html(html); });-
Wraps
XMLHttpRequestor fetch internally. -
Provides cross-browser normalization .
-
Simplifies DOM selection and updates (
$("#id")). -
Handles callbacks inline.
-
At scale, it avoids repeated verbose
fetch()+innerHTMLcalls.
-
Web-Frameworks
ExpressJS
-
npm install express --save.
Exemplos
-
GET básico:
import express from 'npm:express'; const app = express(); app.get('/', (req: express.Request, res: express.Response) => { res.send('Hello World!'); }); app.listen(3000, () => { console.log('Server is running on http://localhost:3000'); }); -
GET com body:
import express from 'npm:express'; const app = express(); app.use(express.json()); app.get('/oi', (req: express.Request, res: express.Response) => { console.log(request.body); res.send('Hello World!'); }); app.listen(3000, () => { console.log('Server is running on http://localhost:3000'); }); -
GET com "Router":
-
Supostamente Ă© tipo pastas da URL.
-
A URL completa Ă© no formato
https://discord.com/api/v9/channels
import express from 'npm:express'; const app = express(); app.use(express.json()); const api = express.Router(); api.get('/channels', (request: express.Request, response: express.Response) => { }); api.get('/users', (request: express.Request, response: express.Response) => { }); api.use('/api/v9', api); app.listen(3000, () => { console.log('Server is running on http://localhost:3000'); }); -
-
GET com ID:
import express from 'npm:express'; const app = express(); app.use(express.json()); app.get('/produtos/:id', (request: express.Request, response: express.Response) => { const {id} = request.params; res.send(`ID pedido: ${id}`); }); app.listen(3000, () => { console.log('Server is running on http://localhost:3000'); });
Status
-
**Regras:
-
No Express, você só pode enviar uma única resposta para cada requisição, seja ela JSON, texto ou qualquer outro formato.
-
No Express, para evitar o timeout, você deve sempre enviar uma resposta completa usando um dos métodos como
res.send,res.json, oures.end.-
Enviar apenas
res.status(200);não é suficiente no Express. Esse comando define o código de status HTTP para a resposta, mas não a encerra nem envia conteúdo. O cliente continuará aguardando até o timeout porque nenhuma resposta final foi enviada.
-
-
-
**Boas práticas:
-
Nunca chame
res.send,res.jsonoures.endmais de uma vez na mesma requisição. -
Use
console.logou uma biblioteca como Winston para registrar logs do servidor.
-
-
Uso do status:
res.status(200).json(personagem); // Explicitamente define que o Status Ă© 200. res.json(personagem); // Implicitamente define o Status padrĂŁo, que Ă© 200. -
.send:
-
Envia uma resposta ao cliente, que pode incluir um corpo de mensagem (
body). -
Ele formata automaticamente o conteĂşdo, como strings, objetos JSON, buffers ou nĂşmeros.
-
Finaliza a resposta apĂłs o envio.
-
Se usado sem parâmetros (
res.send()), ele enviará um corpo vazio (' 'ou equivalente anull) e definirá automaticamente o cabeçalhoContent-Lengthcomo0. -
Pode inferir o tipo de conteúdo e ajustar o cabeçalho
Content-Typeautomaticamente.
res.send(); // Envia uma resposta com corpo vazio e encerra res.send('Hello World'); // Envia uma string res.send({ message: 'Hello World' }); // Envia um objeto JSON -
-
.end:
-
Finaliza a resposta HTTP sem adicionar cabeçalhos ou fazer formatação adicional.
-
Pode incluir dados diretamente como um buffer ou string, mas não faz formatação automática.
-
Não define automaticamente o cabeçalho
Content-Type. -
Não faz formatação ou inferência do conteúdo.
-
É Ăştil para cenários de respostas de baixo nĂvel.
res.end(); // Finaliza a resposta sem enviar conteĂşdo res.end('Hello World'); // Envia a string e finaliza res.end(Buffer.from('Hello World')); // Envia um buffer e finaliza -
-
**.json:
-
O
.json()converte um objeto JavaScript (ou um valor) para o formato JSON e envia a resposta. -
Ele define automaticamente o cabeçalho
Content-Typeda resposta comoapplication/json, informando ao cliente que a resposta contém dados no formato JSON. -
Também converte o objeto JavaScript para uma string JSON, o que permite que os dados sejam facilmente lidos e interpretados por clientes como navegadores, APIs, ou aplicativos.
res.json(data); -
-
Exemplo 1:
-
NĂŁo funciona:
res.status(500).json({ message: (error as Error).message }); res.send('(get_personagem) Find com erro.'); // Essa linha será ignorada.-
Funciona:
res.status(500).json({ message: (error as Error).message, log: '(get_personagem) Find com erro.' }); -
-
Exemplo 2:
-
Funciona:
res.status(200).send('(put_criaturas) Sucesso.\n');res.status(200).send(); // Responde com 200 e sem conteĂşdo-
NĂŁo funciona:
res.status(200); -
Oak (Deno)
-
Oak .
Deno Serve
Deno.serve(...)
-
.
Databases
Mongoose
About
-
Mongoose .
-
It's a wrapper for MongoDB.
-
Is Mongoose an ORM?
-
Mongoose is not technically an ORM (Object-Relational Mapping), but rather an ODM (Object-Document Mapping).
-
Although both ORM and ODM have similar goals — mapping objects in code to database entities — the difference is the type of database each one handles.
-
Explanations
-
HTTP Server with CRUD API and Mongoose database .
-
The presenter uses Mongoose Atlas, but it should not make a difference.
-
The video is of poor quality and poorly explained, but if you have some background before watching it, it is possible to watch it without quitting.
-
{33:47}:
-
Schema and Model created.
-
Connection established with the Mongoose server.
-
-
{49:10}:
-
Create a GET that receives an ID in the URL as a parameter.
-
-
{58:37}:
-
Update a product based on the ID, with PUT.
-
-
Database
-
-
I don't really know yet where the DB lives on the filesystem.
-
There are files inside
Program Files/mongodb.
-
-
Schemas and Models
-
Creating a Schema and Model:
import mongoose from 'npm:mongoose';
mongoose.connect('mongodb://localhost/meu_banco', { useNewUrlParser: true, useUnifiedTopology: true });
const usuarioSchema = new mongoose.Schema({
nome: { type: String, required: true },
email: { type: String, required: true, unique: true },
idade: { type: Number, min: 18 }
});
const Usuario = mongoose.model('Usuario', usuarioSchema);
-
Collection name:
-
.
-
Documents
-
Via
new Modeland.save
const new_user = new Usuario({
nome: 'John',
email: 'john@email.com',
idade: 25
});
new_user.save()
.then(() => console.log('User saved!'))
.catch((err) => console.log('Error saving the user:', err));
-
Via
.create:
const new_character = await Character.create({
nome: 'John',
});
Validations
-
Taken from the video above .
-
A schema created by default has its properties set as 'not required'.
-
.
-
.
-
.
-
.