Skip to main content
Shopify16 iun. 2026·15 min citire

"Shopify Functions vs Scripts: arhitectura WebAssembly explicată corect (cu limitele oficiale)"

Dragoș-Adrian BuhoiuDragoș-Adrian BuhoiuFondator · Arhitect Ecosisteme Digitale
"Shopify Functions vs Scripts: arhitectura WebAssembly explicată corect (cu limitele oficiale)"
FEATURED.IMG
"Shopify Functions vs Scripts: arhitectura WebAssembly explicată corect (cu limitele oficiale)"
CUPRINS
01TL;DR — diferența reală în 60 de secunde (compilat Wasm vs Ruby interpretat)02Arhitectura în 3 straturi: Graph QL input query → logică Wasm → output JSON declarativ03Modelul input → logică → output (run.graphql → run.rs/run.js → „operations")04Function Targets injectează cod în backend logic-ul Shopify05WASM = compilat, nu interpretat (de ce contează față de Scripts)06Ruby dinamic nu compilează direct la Wasm — de ce Shopify a ales un limbaj static07Argumentul de securitate: „you cannot express anything malicious in Wasm"08Determinism by design: fără random, fără clock, fără STDOUT/STDERR09Fără apeluri externe live by default (network access nuanțat)10Anumite Functions au network access sub restricții; endpoint nesuportat ⇒ 502 Not supported11Output pur declarativ (operații), nu răspuns HTTP — nu manipulezi headere12Limitele oficiale exacte (tabel de citat în articol)13Limite fixe14Limite dinamice (până la 200 line items)15Demontarea miturilor virale (rigoarea care lipsește din top-15)16Runtime-ul se măsoară în INSTRUCTION COUNT (11M), NU în milisecunde17„5ms" e o cifră de blog din 2023, calificată de Shopify ca „machine-dependent and situational"18„100x faster than Scripts" NU apare în nicio sursă oficială Shopify19Optimizări recente: Wasm query API (mai 2025) cu deserializare just-in-time20Rust vs Java Script: când alegi care (onest, nu „Rust întotdeauna")21Disponibilitate și context de migrare (orice plan vs Plus; Scripts sunset 30 iun 2026)22Unghiul de performanță și sustenabilitate

"Arhitectura reală (input GraphQL → Wasm → output JSON), limitele oficiale exacte (instruction count, nu ms), demontarea miturilor virale (100x, 5ms). Surse oficiale citate."

Shopify Functions vs Scripts: arhitectura WebAssembly explicată corect (cu limitele oficiale)

Ultima actualizare: 16 iunie 2026 | Surse: shopify.dev/docs — Functions, shopify.dev/docs/api/functions, shopify.engineering — WebAssembly, shopify.engineering — JavaScript in Wasm

Aproape fiecare blog tehnic despre Shopify Functions repetă aceleași cifre: „de 100 de ori mai rapide decât Scripts", „sub 5ms", „rulează în edge în milisecunde". Niciuna nu apare în documentația oficială curentă.

Acest teardown face ceea ce top-15 din SERP nu face: explică arhitectura reală citând direct sursele oficiale, tabelează limitele exacte și demontează miturile virale cu rigoare factuală.

TL;DR — diferența reală în 60 de secunde (compilat Wasm vs Ruby interpretat)

CriteriuScripts (EOL 30 iun 2026)Functions
LimbajRuby interpretatOrice limbaj → compilat la WebAssembly
RuntimeSandbox izolat, acces complet cartInfrastructura edge Shopify, input/output declarativ
Model dateAcces direct la obiecte RubyGraphQL input query → logică Wasm → JSON output
DeterminismNu explicitBy design: fără random, fără clock, fără STDOUT
Limită runtimeNedocumentată publicInstruction count (11M, dinamic)
Network accessN/A (sandbox Ruby)Nuanțat: unele Functions au, cu restricții
DisponibilitateDoar Shopify PlusOrice plan (public apps) / Plus (custom apps)

Dacă ai ajuns aici din ghidul de migrare Scripts → Functions, deja știi CE trebuie migrat. Acest articol explică DE CE funcționează noua arhitectură.

Arhitectura în 3 straturi:GraphQL input query → logică Wasm → output JSON declarativ

Modelul input → logică → output (run.graphql → run.rs/run.js → „operations")

Functions funcționează pe un model strict de trei pași:

  1. Input: Definești un GraphQL input query (run.graphql) care selectează exact datele de care ai nevoie din contextul Shopify (coș, client, metafields). Shopify rulează acest query înainte de a apela Function-ul și pasează rezultatul JSON ca input.
  2. Logică: Codul tău (Rust, JavaScript sau orice limbaj compilabil la Wasm) procesează input-ul JSON și produce output-ul.
  3. Output: Un document JSON cu o listă de „operații" declarative pe care Shopify le execută. Nu returnezi un cart modificat — returnezi instrucțiuni (ex: „aplică discount de 10% pe linia X").

Citat oficial: „Before calling your target, Shopify runs its associated GraphQL query and passes the resulting JSON data to your target."

Sursa: shopify.dev/docs/api/functions.

Function Targets injectează cod în backend logic-ul Shopify

Function-urile nu sunt endpoint-uri externe apelate prin HTTP. Sunt module Wasm care se injectează în backend logic-ul Shopify la puncte-țintă specifice (targets): discount, delivery customization, payment customization, cart transform, validare.

Citat oficial: „Function Targets inject code into the backend logic of Shopify."

Sursa: shopify.dev/docs — Functions.

WASM = compilat, nu interpretat (de ce contează față de Scripts)

Ruby dinamic nu compilează direct la Wasm — de ce Shopify a ales un limbaj static

Scripts foloseau Ruby — un limbaj dinamic interpretat. Ruby nu poate fi compilat direct la WebAssembly din cauza naturii sale dinamice (duck typing, eval, method_missing).

În implementarea timpurie, Shopify a ales AssemblyScript (un subset de TypeScript compilabil la Wasm) și apoi Rust. Citat oficial: „We decided to go with a statically compiled language and revisit the possibility of dynamic languages in the future."

Astăzi, JavaScript este suportat oficial prin pachetul @shopify/shopify_function (≥2.0.0), dar Shopify recomandă Rust (crate shopify_function ≥1.0.0) pentru performanță superioară: „Languages that compile directly to WebAssembly, such as Rust, perform better than dynamic languages, such as JavaScript."

Surse: shopify.engineering — WebAssembly (18 decembrie 2020) · shopify.dev/docs — programming languages.

Argumentul de securitate:„you cannot express anything malicious in Wasm"

WebAssembly are un avantaj de securitate fundamental:

  • „You cannot express anything malicious in Wasm. You can only express manipulations of the virtual environment and use provided imports."
  • „Wasm executes within a sandboxed stack-based environment, relying upon explicit imports to allow communication with the host."

Asta înseamnă: un Function nu poate accesa fișiere, rețea, memorie partajată sau orice resursă a host-ului fără ca Shopify să o permită explicit prin importuri. Sandbox-ul este arhitectural, nu doar prin convenție.

Sursa: shopify.engineering — WebAssembly (18 decembrie 2020).

Determinism by design:fără random, fără clock, fără STDOUT/STDERR

Citat oficial: „Shopify doesn't allow nondeterminism in functions, which means that you can't use any randomizing or clock functionality in your functions."

De asemenea, nu poți face debug prin STDOUT sau STDERR — output-ul standard nu este capturat. Debug-ul se face prin logurile de eroare documentate (max 1 kB, trunchiate).

Asta e o restricție de design, nu un bug. Shopify vrea ca o Function să producă exact același output pentru același input, indiferent de momentul execuției. Determinismul garantează reproductibilitatea la scară.

Sursa: shopify.dev/docs/api/functions.

Fără apeluri externe live by default (network access nuanțat)

Anumite Functions au network access sub restricții; endpoint nesuportat ⇒ 502 Not supported

Mitul simplificat: „Functions nu au network access deloc." Realitatea e nuanțată:

Network access există pentru anumite Functions, sub restricții stricte. Nu orice Function poate face apeluri externe, și nu către orice endpoint.

Dacă apelezi un endpoint nesuportat, funcția rulează local dar nu se trimite niciun request real — target-ul primește un răspuns cu status „502 — Not supported".

Sursa: shopify.dev/docs — network access.

Output pur declarativ (operații), nu răspuns HTTP — nu manipulezi headere

Un Function nu returnează un răspuns HTTP. Returnează un document JSON cu o listă de operații declarative. Nu manipulezi request headers, nu setezi cookies, nu faci redirect-uri. Shopify procesează operațiile și le aplică în backend.

Asta e diferența fundamentală față de middleware-ul clasic sau serverless functions. Un Shopify Function nu e un endpoint — e o transformare de date.

Limitele oficiale exacte (tabel de citat în articol)

Limite fixe

ResursăLimită
Binar compilat Wasmmax 256 kB
Memorie liniară runtime10.000 kB
Memorie stack runtime512 kB
Loguri scrise1 kB (trunchiat)

Limite dinamice (până la 200 line items)

ResursăLimită (≤200 line items)Peste 200
Instruction count11 milioane instrucțiuniScalează proporțional
Input funcție128 kBScalează proporțional
Output funcție20 kBScalează proporțional

Limita de „instruction count" este cea mai importantă — și cea mai prost înțeleasă. Nu e o limită de timp. Este o limită de complexitate computațională a modulului Wasm.

Sursa: shopify.dev/docs/api/functions.

Demontarea miturilor virale (rigoarea care lipsește din top-15)

Runtime-ul se măsoară în INSTRUCTION COUNT (11M), NU în milisecunde

Erorile de runtime documentate oficial includ:

  • InstructionCountLimitExceededError
  • StackMemoryLimitExceededError
  • LinearMemoryLimitExceededError
  • OutputTooLargeError
  • InputSizeLimitExceededError

Observă: niciun ExecutionTimeLimitExceededError. Pagina oficială de limite nu publică niciun prag de timp de execuție în milisecunde.

Surse: shopify.dev/docs — monitoring and errors · shopify.dev/docs/api/functions.

„5ms" e o cifră de blog din 2023, calificată de Shopify ca „machine-dependent and situational"

Cifra de 5ms provine dintr-un articol Shopify Engineering din februarie 2023 despre JavaScript în WebAssembly. Contextul exact: era o constrângere de dezvoltare internă, nu o limită de produs.

Citat oficial: „The module must not run longer than 5ms" — dar Shopify o califică explicit ca fiind „a very machine-dependent and situational constraint."

Nu apare în documentația curentă de produs. Nu e o limită oficială. Este o cifră de inginerie din 2023 care a fost preluată viral de bloguri fără context.

Sursa: shopify.engineering — JavaScript in WebAssembly for Shopify Functions (9 februarie 2023).

„100x faster than Scripts" NU apare în nicio sursă oficială Shopify

Am verificat: shopify.dev, shopify.engineering, changelog.shopify.com, help.shopify.com. Niciun document oficial Shopify conține afirmația „100x faster" sau „de 100 de ori mai rapid".

Este o cifră de marketing apărută în bloguri terțe. Poate fi plausibilă ca ordin de mărime (Wasm compilat vs Ruby interpretat), dar nu este o afirmație oficială Shopify și nu trebuie citată ca atare.

Optimizări recente:Wasm query API (mai 2025) cu deserializare just-in-time

În mai 2025, Shopify a lansat Functions Wasm query API — o optimizare care permite deserializare just-in-time: Function-ul citește doar câmpurile efectiv folosite din input, eliminând overhead-ul de a include un parser JSON complet în binar.

Rezultat: funcții mai mici (sub limita de 256 kB) și mai eficiente (mai puține instrucțiuni consumate pe parsing).

Dacă ai Functions existente cu binar aproape de 256 kB, aceasta e o cale concretă de optimizare.

Sursa: shopify.dev/changelog — Functions Wasm query API (21 mai 2025).

Rust vs JavaScript:când alegi care (onest, nu „Rust întotdeauna")

Shopify recomandă Rust. Dar recomandarea onestă e mai nuanțată:

Alege Rust când:

  • Ai Function-uri complexe aproape de limita de 11M instrucțiuni
  • Binarul trebuie să rămână sub 256 kB (Rust produce binare semnificativ mai mici)
  • Echipa ta are experiență Rust sau e dispusă să investească în învățare
  • Performanța e critică (volume mari de line items)

Alege JavaScript când:

  • Ai developeri familiari cu JS/TS care trebuie să livreze rapid
  • Logica de business e simplă (discount pe tag, filtru de plată, redenumire transport)
  • Iterezi frecvent și vrei un ciclu de dezvoltare mai scurt
  • Ești confortabil cu overhead-ul mai mare (binar mai mare, mai multe instrucțiuni)

Nu e o alegere absolută. E un trade-off între performanță și productivitate. Functions JS rulează în producție pe milioane de magazine Shopify.

Surse: shopify.dev/docs — programming languages.

Disponibilitate și context de migrare (orice plan vs Plus; Scripts sunset 30 iun 2026)

  • Orice plan: poate folosi aplicații publice din App Store care conțin Functions.
  • Doar Plus: poate rula custom apps cu Function APIs construite cu Shopify CLI.
  • Batch limit: un singur Function API poate executa până la 25 de funcții într-un batch (crescut de la 5), pentru Payment/Delivery customizations, Cart/checkout validations și Fulfillment constraints.

Scripts (Script Editor) erau disponibile exclusiv pe Shopify Plus. Sunset-ul e pe 30 iunie 2026 — pașii practici de migrare sunt detaliați în ghidul nostru complet de migrare.

Surse: shopify.dev/docs/api/functions · shopify.dev/changelog — 25 functions limit (21 mai 2025).

Unghiul de performanță și sustenabilitate

Din perspectiva ingineriei de mediu pe care o practicăm la Verdant Mindset:

Functions (WebAssembly pe infra edge) vs Scripts (Ruby interpretat pe server) = mai puțin CPU per execuție. La scara checkout-urilor Shopify (milioane zilnic), asta contează.

Dar nu inventăm cifre de CO2 — nu avem surse oficiale pentru impactul exact. Ce știm:

  • Cod compilat Wasm e deterministic mai eficient decât Ruby interpretat.
  • Eliminarea app-urilor terțe cu funcționalitate similară (acum nativă) reduce payload-ul JS al storefront-ului.
  • Dovada VM: TTFB de 0.21s pe Shopify (Fitness Library) prin eliminarea app-urilor redundante.

Pentru arhitectura completă SEO + performanță pe Shopify: ghidul nostru de arhitectură SEO Shopify.

FAQ.PROTOCOL

Întrebări frecvente

Scripts rulau cod Ruby interpretat într-un sandbox izolat cu acces direct la obiectul cart. Functions rulează module WebAssembly compilate pe infrastructura edge Shopify, cu input GraphQL și output JSON declarativ. Diferența fundamentală: Functions sunt deterministe by design și nu au acces direct la obiecte — totul trece prin query-uri declarative.
Ambele sunt oficial suportate. Shopify recomandă Rust pentru performanță (binare mai mici, mai puține instrucțiuni), dar JavaScript este funcțional și larg folosit. Alegerea depinde de expertiza echipei și complexitatea logicii.
Afirmația „100x faster" nu apare în nicio sursă oficială Shopify. Este o cifră de marketing din bloguri terțe. Functions sunt probabil semnificativ mai rapide (Wasm compilat vs Ruby interpretat), dar Shopify nu publică comparații de performanță oficiale.
Limita oficială curentă este exprimată în instruction count: 11 milioane de instrucțiuni Wasm (pentru până la 200 line items, scalează proporțional peste). Nu există o limită publicată în milisecunde. Cifra de „5ms" e o constrângere internă de inginerie din 2023, calificată explicit de Shopify ca „machine-dependent and situational".
Nuanțat. Anumite Functions au network access sub restricții stricte. Nu toate Functions pot face apeluri externe, și nu către orice endpoint. Dacă apelezi un endpoint nesuportat, funcția rulează local dar nu se trimite niciun request real — primești status „502 — Not supported".
Binar compilat Wasm: max 256 kB. Memorie liniară runtime: 10.000 kB. Memorie stack: 512 kB. Loguri: 1 kB (trunchiat). Input: 128 kB (dinamic). Output: 20 kB (dinamic). Instruction count: 11M (dinamic). Limitele dinamice scalează proporțional peste 200 line items.
Ruby este un limbaj dinamic care nu poate fi compilat direct la Wasm. Shopify a ales WebAssembly pentru trei motive: (1) determinism — aceleași date de intrare produc același rezultat, (2) securitate — „you cannot express anything malicious in Wasm", (3) performanță — cod compilat nativ vs interpretat. --- Ultima actualizare: 16 iunie 2026 Surse oficiale folosite: shopify.dev/docs — Functions · shopify.dev/docs/api/functions · shopify.engineering — WebAssembly · shopify.engineering — JavaScript in Wasm · shopify.dev/changelog — Wasm query API · shopify.dev/docs — network access · shopify.dev/docs — monitoring and errors Vrei un audit tehnic al magazinului tău Shopify? Echipa noastră construiește ecosisteme Shopify sustenabile. ```json { "@context": "https://schema.org", "@type": "TechArticle", "headline": "Shopify Functions vs Scripts: arhitectura WebAssembly explicată corect (cu limitele oficiale)", "description": "Arhitectura reală (input GraphQL → Wasm → output JSON), limitele oficiale exacte (instruction count, nu ms), demontarea miturilor virale (100x, 5ms). Surse oficiale citate.", "datePublished": "2026-06-16", "dateModified": "2026-06-16", "author": { "@type": "Organization", "name": "Verdant Mindset", "url": "https://verdantmindset.com" }, "publisher": { "@type": "Organization", "name": "Verdant Mindset", "url": "https://verdantmindset.com" }, "inLanguage": "ro", "mainEntityOfPage": "https://verdantmindset.com/resurse/shopify-functions-vs-scripts" } ``` ```json { "@context": "https://schema.org", "@type": "FAQPage", "mainEntity": [ { "@type": "Question", "name": "Care e diferența arhitecturală dintre Shopify Functions și Scripts?", "acceptedAnswer": { "@type": "Answer", "text": "Scripts rulau cod Ruby interpretat într-un sandbox izolat cu acces direct la obiectul cart. Functions rulează module WebAssembly compilate pe infrastructura edge Shopify, cu input GraphQL și output JSON declarativ." } }, { "@type": "Question", "name": "În ce limbaj scrii Shopify Functions: Rust sau JavaScript?", "acceptedAnswer": { "@type": "Answer", "text": "Ambele sunt oficial suportate. Shopify recomandă Rust pentru performanță, dar JavaScript este funcțional și larg folosit. Alegerea depinde de expertiza echipei și complexitatea logicii." } }, { "@type": "Question", "name": "Sunt Shopify Functions de 100x mai rapide decât Scripts?", "acceptedAnswer": { "@type": "Answer", "text": "Afirmația 100x faster nu apare în nicio sursă oficială Shopify. Este o cifră de marketing din bloguri terțe." } }, { "@type": "Question", "name": "Care e limita reală de runtime a unei Shopify Function?", "acceptedAnswer": { "@type": "Answer", "text": "Limita oficială curentă este instruction count: 11 milioane de instrucțiuni Wasm. Nu există o limită publicată în milisecunde." } }, { "@type": "Question", "name": "Pot face apeluri externe dintr-o Shopify Function?", "acceptedAnswer": { "@type": "Answer", "text": "Nuanțat. Anumite Functions au network access sub restricții stricte. Endpoint nesuportat returnează 502 Not supported." } }, { "@type": "Question", "name": "Care sunt limitele oficiale de mărime pentru o Shopify Function?", "acceptedAnswer": { "@type": "Answer", "text": "Binar Wasm: max 256 kB. Memorie liniară: 10.000 kB. Stack: 512 kB. Loguri: 1 kB. Input: 128 kB (dinamic). Output: 20 kB (dinamic). Instruction count: 11M (dinamic)." } }, { "@type": "Question", "name": "De ce folosește Shopify WebAssembly în loc de Ruby?", "acceptedAnswer": { "@type": "Answer", "text": "Ruby este un limbaj dinamic care nu compilează direct la Wasm. Shopify a ales WebAssembly pentru determinism, securitate (sandbox stack-based) și performanță." } } ] } ```