Recent Posts
Archives

Posts Tagged ‘JavaScript’

PostHeaderIcon [NDCMelbourne2025] How to Work with Generative AI in JavaScript – Phil Nash

Phil Nash, a developer relations engineer at DataStax, delivers a comprehensive guide to leveraging generative AI in JavaScript at NDC Melbourne 2025. His talk demystifies the process of building AI-powered applications, emphasizing that JavaScript developers can harness existing skills to create sophisticated solutions without needing deep machine learning expertise. Through practical examples and insights into tools like Gemini and retrieval-augmented generation (RAG), Phil empowers developers to explore this rapidly evolving field.

Understanding Generative AI Fundamentals

Phil begins by addressing the excitement surrounding generative AI, noting its accessibility since the release of the GPT-3.5 API two years ago. He emphasizes that JavaScript developers are well-positioned to engage with AI due to robust tooling and APIs, despite the field’s Python-centric origins. Using Google’s Gemini model as an example, Phil demonstrates how to generate content with minimal code, highlighting the importance of understanding core concepts like token generation and model behavior.

He explains tokenization, using OpenAI’s byte pair encoding as an example, where text is broken into probabilistic tokens. Parameters like top-k, top-p, and temperature allow developers to control output randomness, with Phil cautioning against overly high settings that produce nonsensical results, humorously illustrated by a chaotic AI-generated story about a gnome.

Enhancing AI with Prompt Engineering

Prompt engineering emerges as a critical skill for refining AI outputs. Phil contrasts zero-shot prompting, which offers minimal context, with techniques like providing examples or system prompts to guide model behavior. For instance, a system prompt defining a “capital city assistant” ensures concise, accurate responses. He also explores chain-of-thought prompting, where instructing the model to think step-by-step improves its ability to solve complex problems, such as a modified river-crossing riddle.

Phil underscores the need for evaluation to ensure prompt reliability, as slight changes can significantly alter outcomes. This structured approach transforms prompt engineering from guesswork into a disciplined practice, enabling developers to tailor AI responses effectively.

Retrieval-Augmented Generation for Contextual Awareness

To address AI models’ limitations, such as outdated or private data, Phil introduces retrieval-augmented generation (RAG). RAG enhances models by integrating external data, like conference talk descriptions, into prompts. He explains how vector embeddings—multidimensional representations of text—enable semantic searches, using cosine similarity to find relevant content. With DataStax’s Astra DB, developers can store and query vectorized data efficiently, as demonstrated in a demo where Phil’s bot retrieves details about NDC Melbourne talks.

This approach allows AI to provide contextually relevant answers, such as identifying AI-related talks or conference events, making it a powerful tool for building intelligent applications.

Streaming Responses and Building Agents

Phil highlights the importance of user experience, noting that AI responses can be slow. Streaming, supported by APIs like Gemini’s generateContentStream, delivers tokens incrementally, improving perceived performance. He demonstrates streaming results to a webpage using JavaScript’s fetch and text decoder streams, showcasing how to create responsive front-end experiences.

The talk culminates with AI agents, which Phil describes as systems that perceive, reason, plan, and act using tools. By defining functions in JSON schema, developers can enable models to perform tasks like arithmetic or fetching web content. A demo bot uses tools to troubleshoot a keyboard issue and query GitHub, illustrating agents’ potential to solve complex problems dynamically.

Conclusion: Empowering JavaScript Developers

Phil concludes by encouraging developers to experiment with generative AI, leveraging tools like Langflow for visual prototyping and exploring browser-based models like Gemini Nano. His talk is a call to action, urging JavaScript developers to build innovative applications by combining AI capabilities with their existing expertise. By mastering prompt engineering, RAG, streaming, and agents, developers can create powerful, user-centric solutions.

Links:

PostHeaderIcon [DevoxxFR2025] Winamax’s Journey Towards Cross-Platform

In today’s multi-device world, providing a consistent and high-quality user experience across various platforms is a significant challenge for software companies. For online gaming and betting platforms like Winamax, reaching users on desktop, web, and mobile devices is paramount. Anthony Maffert and Florian Yger from Winamax shared their insightful experience report detailing the company’s ambitious journey to unify their frontend applications onto a single cross-platform engine. Their presentation explored the technical challenges, the architectural decisions, and the concrete lessons learned during this migration, showcasing how they leveraged modern web technologies like JavaScript, React, and WebGL to achieve a unified codebase for their desktop and mobile applications.

The Challenge of a Fragmented Frontend

Winamax initially faced a fragmented frontend landscape, with separate native applications for desktop (Windows, macOS) and mobile (iOS, Android), alongside their web platform. Maintaining and developing features across these disparate codebases was inefficient, leading to duplicated efforts, inconsistencies in user experience, and slower delivery of new features. The technical debt associated with supporting multiple platforms became a significant hurdle. Anthony and Florian highlighted the clear business and technical need to consolidate their frontend development onto a single platform that could target all the required devices while maintaining performance and a rich user experience, especially crucial for a real-time application like online poker.

Choosing a Cross-Platform Engine

After evaluating various options, Winamax made the strategic decision to adopt a cross-platform approach based on web technologies. They chose to leverage JavaScript, specifically within the React framework, for building their user interfaces. For rendering the complex and dynamic visuals required for a poker client, they opted for WebGL, a web standard for rendering 2D and 3D graphics within a browser, which can also be utilized in cross-platform frameworks. Their previous experience with JavaScript on their web platform played a role in this decision. The core idea was to build a single application logic and UI layer using these web technologies and then deploy it across desktop and mobile using wrapper technologies (like Electron for desktop and potentially variations for mobile, although the primary focus of this talk seemed to be the desktop migration).

The Migration Process and Lessons Learned

Anthony and Florian shared their experience with the migration process, which was a phased approach given the complexity of a live gaming platform. They discussed the technical challenges encountered, such as integrating native device functionalities (like file system access for desktop) within the web technology stack, optimizing WebGL rendering performance for different hardware, and ensuring a smooth transition for existing users. They touched upon the architectural changes required to support a unified codebase, potentially involving a clear separation between the cross-platform UI logic and any platform-specific native modules or integrations. Key lessons learned included the importance of careful planning, thorough testing on all target platforms, investing in performance optimization, and managing the technical debt during the transition. They also highlighted the benefits reaped from this migration, including faster feature development, reduced maintenance overhead, improved consistency across platforms, and the ability to leverage a larger pool of web developers. The presentation offered a valuable case study for other organizations considering a similar move towards cross-platform development using web technologies.

Links:

PostHeaderIcon [NDCMelbourne2025] A Look At Modern Web APIs You Might Not Know – Julian Burr

As web technologies evolve, the capabilities of browsers have expanded far beyond their traditional roles, often rendering the need for native applications obsolete for certain functionalities. Julian Burr, a front-end engineer with a passion for design systems, delivers an engaging exploration of modern web APIs at NDC Melbourne 2025. Through his demo application, stopme.io—a stopwatch-as-a-service platform—Julian showcases how these APIs can enhance user experiences while adhering to the principle of progressive enhancement. His talk illuminates the power of web APIs to bridge the gap between web and native app experiences, offering practical insights for developers.

The Philosophy of Progressive Enhancement

Julian begins by championing progressive enhancement, a design philosophy that ensures baseline functionality for all users while delivering enhanced experiences for those with modern browsers. Quoting Mozilla, he defines it as providing essential content to as many users as possible while optimizing for advanced environments. This approach is critical when integrating web APIs, as it prevents over-reliance on features that may not be universally supported. For instance, in stopme.io, Julian ensures core stopwatch functionality remains accessible, with APIs adding value only when available. This philosophy guides his exploration, ensuring inclusivity and robustness in application design.

Observing the Web: Resize and Intersection Observers

The first category Julian explores is observability APIs, starting with the Resize Observer and Intersection Observer. These APIs, widely supported, allow developers to monitor changes in DOM element sizes and visibility within the viewport. In stopme.io, Julian uses the Intersection Observer to load JavaScript chunks only when components become visible, optimizing performance. While CSS container queries address styling needs, these APIs enable dynamic behavioral changes, making them invaluable for frameworks like Astro that rely on code splitting. Julian emphasizes their relevance, as they underpin many modern front-end optimizations, enhancing user experience without compromising accessibility.

Enhancing User Context: Network and Battery Status

Julian then delves into APIs that provide contextual awareness, such as the Page Visibility API, Network Information API, and Battery Status API. The Page Visibility API allows stopme.io to update the browser title bar with the timer status when the tab is inactive, enabling users to multitask. The Network Information API offers insights into connection types, allowing developers to serve lower-resolution assets on cellular networks. Similarly, the Battery Status API warns users of potential disruptions due to low battery, as demonstrated when stopme.io alerts users about long-running timers. Julian cautions about fingerprinting risks, noting that browser vendors intentionally reduce accuracy to protect privacy, aligning with progressive enhancement principles.

Elevating Components: Screen Wake Lock and Vibration

Moving to component enhancement, Julian highlights the Screen Wake Lock and Vibration APIs. The Screen Wake Lock API prevents devices from entering sleep mode during critical tasks, such as keeping stopme.io’s timer visible. The Vibration API adds haptic feedback, like notifying users when a timer finishes, with customizable patterns for engaging effects. Julian stresses user control, suggesting toggles to avoid intrusive experiences. While these APIs—often Chrome-centric—enhance interactivity, Julian underscores the need for fallback options to maintain functionality across browsers, ensuring no user is excluded.

Native-Like Experiences: File System, Clipboard, and Share APIs

Julian showcases APIs that rival native app capabilities, including the File System, Clipboard, and Share APIs. The File System API enables file picker interactions, while the Clipboard API facilitates seamless copy-paste operations. The Share API, used in stopme.io, triggers native sharing dialogs, simplifying content distribution across platforms. These APIs, inspired by tools like Cordova, reflect the web’s evolution toward native-like functionality. Julian notes their security mechanisms, such as transient activation for Clipboard API, which require user interaction to prevent misuse, ensuring both usability and safety.

Streamlining Authentication: Web OTP and Credential Management

Authentication APIs, such as Web OTP and Credential Management, offer seamless login experiences. The Web OTP API automates SMS-based one-time password entry, as demonstrated in stopme.io, where Chrome facilitates code sharing across devices. The Credential Management API streamlines password storage and retrieval, reducing login friction. Julian highlights their synergy with the Web Authentication API, which supports passwordless logins via biometrics. These APIs, widely available, enhance security and user convenience, making them essential for modern web applications.

Links:

PostHeaderIcon [DotJs2024] Your App Crashes My Browser

Amid the ceaseless churn of web innovation, a stealthy saboteur lurks: memory leaks that silently erode browser vitality, culminating in the dreaded “Out of Memory” epitaph. Stoyan Stefanov, a trailblazing entrepreneur and web performance sage with roots at Facebook, confronted this scourge at dotJS 2024. Once a fixture in optimizing vast social feeds, Stoyan transitioned from crisis aversion—hard reloads post-navigation—to empowerment through diagnostics. His manifesto: arm developers with telemetry and sleuthing to exorcise these phantoms, ensuring apps endure without devouring RAM.

Stoyan’s alarm rang true via Nolan Lawson’s audit: a decade’s top SPAs unanimously hemorrhaged, underscoring leaks’ ubiquity even among elite codebases. Personal scars abounded—from a social giant’s browser-crushing sprawl, mitigated by crude resets—to the thrill of unearthing culprits sans autopsy. The panacea commences with candor: the Reporting API, a beacon flagging crashes in the wild, piping diagnostics to endpoints for pattern mining. This passive vigilance—triggered on OOM—unmasks field frailties, from rogue closures retaining DOM vestiges to event sentinels orphaned post-unmount.

Diagnosis demands ritual: heap snapshots bracketing actions, GC sweeps purifying baselines, diffs revealing retainers. Stoyan evangelized Memlab, Facebook’s CLI oracle, automating Puppeteer-driven cycles—load, act, revert—yielding lucid diffs: “1,000 objects via EventListener cascade.” For the uninitiated, his Recorder extension chronicles clicks into scenario scripts, demystifying Puppeteer. Leaks manifest insidiously: un-nullified globals, listener phantoms in React class components—addEventListener sans symmetric removal—hoarding callbacks eternally.

Remediation rings simple: sever references—null assignments, framework hooks like useEffect cleanups—unleashing GC’s mercy. Stoyan’s ethos: paranoia pays; leaks infest, but tools tame. From Memlab’s precision on map apps—hotel overlays persisting post-dismiss—to listener audits, vigilance yields fluidity. In an age of sprawling SPAs, this vigilance isn’t luxury but lifeline, sparing users frustration and browsers demise.

Unveiling Leaks in the Wild

Stoyan spotlighted Reporting API’s prowess: crash telemetry streams to logs, correlating OOM with usage spikes. Nolan’s Speedline probe affirmed: elite apps falter uniformly, from unpruned caches to eternal timers. Proactive profiling—snapshots pre/post actions—exposes retain cycles, Memlab automating to spotlight listener detritus or closure traps.

Tools and Tactics for Eradication

Memlab’s symphony: Puppeteer orchestration, intelligent diffs tracing leaks to sources—e.g., 1K objects via unremoved handlers. Stoyan’s Recorder eases entry, click-to-script. Fixes favor finality: removeEventListener in disposals, nulls for orphans. Paranoia’s yield: resilient apps, jubilant users.

Links:

PostHeaderIcon [DotJs2025] Live Coding with Ryan Dahl: Deno and OpenTelemetry

Observability’s quest in serverless seas once drowned in bespoke boilerplate; enter Deno’s alchemy, fusing runtime rigor with OpenTelemetry’s ubiquity. Ryan Dahl, Node’s progenitor and Deno Land’s CEO, live-wove this tapestry at dotJS 2025, showcasing zero-config traces illuminating JS’s shadowy underbelly. From UCSD’s mathematical meadows to ML’s machine wilds, Ryan’s odyssey—secure-by-default Deno, TypeScript’s native nest—now embraces OTEL’s triad: logs, metrics, spans.

Ryan’s canvas: a toy API, user IDs fetched, errors eventual—mundane yet ripe for revelation. Deno’s infusion: Deno.metrics(), console.log piped to OTEL, spans auto-spanning HTTP arcs. Exporter’s elegance: Jaeger console, traces unfurling waterfalls—entrypoints to exits, attributes annotating arcs. Live, Ryan scaffolded: import OTEL, configure exporter, instrument fetches—redeploy to Deno Deploy, logs and traces blooming in tandem. Nanoseconds’ narrative: cold starts eclipsed, polyglot peace via WIT interfaces—Rust greeters yielding to TS handlers.

This symbiosis scales: production probes sans proxies, Deno Deploy’s horizon harboring holistic views. Ryan’s aside: Oracle’s JS trademark tyranny—a cease-and-desist specter stifling “JSConf”—spurred javascript.tm’s petition, amassing allies against anachronistic anchors.

Deno’s decree: OTEL’s open arms, JS’s joyful instrumentation—debugging demystified, deployments discerned.

Instrumentation’s Instantaneity

Ryan rendered realms: metrics via Deno.metrics(), logs laced with OTEL, spans spanning sans strife. Jaeger’s vista: waterfalls whispering workflows, attributes authoring arcs—live, a fetch’s fate traced, errors etched eternally.

Horizons and Heresies

Deno Deploy’s dawn: traces native, nanoseconds’ narrative. Ryan rallied: sign javascript.tm, reclaim JS’s soul—petition’s progress, public’s power against Oracle’s overhang.

Links:

PostHeaderIcon [DotJs2025] Using AI with JavaScript: Good Idea?

Amid the AI deluge reshaping codecraft, a tantalizing prospect emerges: harnessing neural nets natively in JavaScript, sidestepping Python’s quagmires or API tolls. Wes Bos, a prolific Canadian educator whose Syntax.fm podcast and courses have schooled half a million in JS mastery, probed this frontier at dotJS 2025. Renowned for demystifying ES6 and React, Wes extolled browser-bound inference via Transformers.js, weighing its virtues—privacy’s fortress, latency’s lightning—against hardware’s hurdles, affirming JS’s prowess for sundry smart apps.

Wes’s overture skewered the status quo: cloud fetches or Python purgatory, both anathema to JS purists. His heresy: embed LLMs client-side, ONNX Runtime fueling Hugging Face’s arsenal—sentiment sifters, translation tomes, even Stable Diffusion’s slimmer kin. Transformers.js’s pipeline paradigm gleams: import, instantiate (pipeline('sentiment-analysis')), infer (result = await pipe(input)). Wes demoed a local scribe: prompt yields prose, all sans servers, WebGPU accelerating where GPUs oblige. Onyx.js, his bespoke wrapper, streamlines: model loads, GPU probes, inferences ignite—be it code completion or image captioning.

Trade-offs tempered triumph. Footprints fluctuate: 2MB wisps to 2GB behemoths, browser quotas (Safari’s 2GB cap) constraining colossi. Compute cedes to client: beefy rigs revel, mobiles murmur—Wes likened Roblox’s drain to LLM’s voracity. Yet, upsides dazzle: zero egress fees, data’s domicile (GDPR’s grace), offline oases. 2025’s tide—Chrome’s stable WebNN, Firefox’s flag—heralds ubiquity, Wes forecasting six-month Safari stability. His verdict: JS, with its ubiquity and ecosystem, carves niches where immediacy reigns—chatbots, AR filters—not every oracle, but myriad muses.

Wes’s zeal stemmed personal: from receipt printers to microcontroller React, JS’s whimsy fuels folly. Transformers.js empowers prototypes unbound—anime avatars, code clairvoyants—inviting creators to conjure without concessions.

Client-Side Sorcery Unveiled

Wes unpacked pipelines: sentiment sorters, summarizers—Hugging Face’s trove, ONNX-optimized. Onyx’s facade: await onnx.loadModel('gpt2'), GPU fallback, inferences instantaneous. WebGPU’s dawn (Chrome 2025 stable) unlocks acceleration, privacy paramount—no telemetry trails.

Balancing Bytes and Burdens

Models’ mass mandates moderation: slim variants suffice for mobile, diffusion downsized. Battery’s bite, CPU’s churn—Wes warned of Roblox parallels—yet offline allure and cost calculus compel. JS’s sinew: ecosystem’s expanse, browser’s bastion, birthing bespoke brains.

Links:

PostHeaderIcon [DotJs2024] Remixing the Bundler

The demarcation between libraries and frameworks is dissolving, yielding hybrid entities that democratize web app assembly. Mark Dalgleish, co-creator of CSS Modules and core Remix team member from Melbourne, unpacked this metamorphosis at dotJS 2024. Amid jet-lag’s haze—bedtime Down Under—Dalgleish chronicled Remix’s pivot from bundler overlord to Vite plugin, illuminating tradeoffs and consumer boons in an ecosystem where React’s library purity meets framework ambitions.

Dalgleish contextualized via React docs: libraries like React invite framework augmentation for routing, data, builds. React Router, a routing stalwart since React’s infancy (halving installs pair it), contrasts Remix’s full-stack ethos—CLI-driven dev/builds, config files dictating structure, file-based routing. Yet, Remix bootstraps atop Router, exporting its APIs for familiarity: “React Router, the framework.” Bundler ownership defined early Remix: esbuild’s velocity supplanted Rollup, plugins added TypeScript, assets, HMR, polyfills. Dalgleish confessed: stewarding bundlers diverts from core missions, spawning endless edge requests—new loaders, plugins—while craving low-level tweaks.

Vite’s ascent inverted norms: frameworks as plugins, not vice versa. Remix’s migration yielded: dev servers with HMR, preview pipelines, configurable builds—Vite’s gifts. Plugins now encode conventions: Remix’s dictates dev flows, output paths, sans CLI bloat. App code imports Router directly, indirection erased; Remix’s loaders, actions, nested routing infuse the library. React Conf 2024 announced fusion: Remix upstreams into Router, empowering half React’s users with framework superpowers—optional via Vite plugin. Dalgleish reframed: Router remains library-flexible (serverless, static), conventions pluggable.

Implications abound: Vite’s vibrant community accelerates frameworks; simplicity shrinks footprints—delete years of code. Barrier-lowered authorship invites experimentation; consumers port plugins across Vite realms, learning once. Maintainers unburden, focusing essence. Dalgleish hailed Vite’s platform ethos—Evan You’s spark, team’s nurture—propelling Remix’s (now Router’s) trajectory.

Blurring Library-Framework Contours

Dalgleish traced Remix’s esbuild era: speed wins, but ownership’s toll—HMR hacks, polyfill webs—eclipsed. Vite plugins liberate: conventions as hooks, library code unadorned. Router’s merger embeds Remix’s data mutations, streaming, into routing’s heart—framework sans moniker.

Vite’s Empowerment for Builders

Vite furnishes dev/build scaffolds; plugins customize sans reinvention. Dalgleish envisioned: nascent frameworks plugin-first, ecosystems interoperable. Consumers gain portability—plugins transfer, features standardize—while authors prune maintenance, amplifying innovation.

Links:

PostHeaderIcon [DotJs2024] Adding Undo/Redo to Complex Web Apps

Enhancing user agency in labyrinthine applications hinges on forgiving interactions, where missteps dissolve with a keystroke. Bassel Ghandour, a senior software engineer at Contentsquare, distilled this essence into a brisk yet profound primer at dotJS 2024. From Paris’s vibrant tech scene—now his U.S. outpost—Ghandour lamented a botched virtual Tokyo greeting, swiftly invoking undo’s allure. His focus: retrofitting undo/redo into state-heavy web apps, sidestepping snapshot pitfalls for action-centric resilience.

Ghandour commenced with state management basics in a todo app: frontend mirrors app state, enter-press morphs it—additions, UI ripples. Naive undo? Timestamped snapshots, hopping between epochs. Reality intrudes: actions cascade side effects, backend ops interweave, concurrency clashes. Rapid todo barrages spawn interleaved sequences; snapshot reversion mid-thread invites chaos. Solution: encapsulate sequences under UUIDs, treating batches as atomic units. Parallel: forge inverses—add’s delete, toggle’s revert—mapping each to its antithesis.

This duality—do and undo in tandem—preserves fidelity. User crafts todo: UUID wraps creation, displays; inverse queues deletion. Subsequent show-toggle: nested UUID, inverse queued. Undo invokes the stack’s apex inverse, state reverts cleanly; redo replays forwards. Ghandour’s flow: capture actions, inverse-map, sequence-bundle, command-apply. Backend sync? Optimistic updates, rollbacks on failure. Contentsquare’s engineering blog details implementations, from Redux sagas to custom dispatchers.

Ghandour’s brevity belied depth: this pattern scales to e-commerce carts, design canvases, empowering serene navigation amid complexity. By prioritizing actions over states, developers liberate users, fostering trust in intricate digital environs.

Encapsulating Actions for Resilience

Ghandour advocated UUID-wrapped sequences, neutralizing concurrency: todo volleys become discrete do/undo pairs, applied reversibly. Inverse mapping—add-to-delete—ensures symmetry, backend integrations via optimistic commits. This sidesteps snapshot bloat, embracing flux with grace.

Implementing Undo/Redo Commands

Stacks manage history: push do with inverse, pop applies antithesis. Redo mirrors. Ghandour teased Contentsquare’s saga: Redux orchestration, UI hooks triggering cascades—scalable, testable, user-delighting.

Links:

PostHeaderIcon [DevoxxBE2024] How JavaScript Happened: A Short History of Programming Languages

In an engaging session at Devoxx Belgium 2024, Mark Rendle traced the evolution of programming languages leading to JavaScript’s creation in 1995. Titled “How JavaScript Happened: A Short History of Programming Languages,” the talk blended humor and history, from Ada Lovelace’s 1840s program to JavaScript’s rapid development for Netscape Navigator 2.0. Despite a brief battery scare during the presentation, Rendle’s storytelling and FizzBuzz examples across languages captivated the audience, offering insights into language design and JavaScript’s eclectic origins.

The Dawn of Programming

Rendle began in the 1830s with Ada Lovelace, who wrote the first program for Charles Babbage’s unbuilt Analytical Engine, introducing programming notation 120 years before computers existed. The 1940s saw programmable machines like Colossus, built to crack German ciphers, and ENIAC, programmed by women who deciphered its operation without manuals. These early systems, configured via patch cables, laid the groundwork for modern computing, though programming remained labor-intensive.

The Rise of High-Level Languages

The 1950s marked a shift with Fortran, created by John Backus to simplify machine code translation for IBM’s 701 mainframe. Fortran introduced if statements, the asterisk for multiplication (due to punch card limitations), and the iterator variable i, still ubiquitous today. ALGOL 58 and 60 followed, bringing block structures, if-then-else, and BNF grammar, formalized by Backus. Lisp, developed by John McCarthy, introduced first-class functions, the heap, and early garbage collection, while Simula pioneered object-oriented programming with classes and inheritance.

From APL to C and Beyond

Rendle highlighted APL’s concise syntax, enabled by its unique keyboard and dynamic typing, influencing JavaScript’s flexibility. The 1960s and 70s saw BCPL, B, and C, with C introducing curly braces, truthiness, and the iconic “hello world” program. Smalltalk added reflection, virtual machines, and the console, while ML introduced functional programming concepts like arrow functions. Scheme, a simplified Lisp, directly influenced JavaScript’s initial design as a browser scripting language, shaped to compete with Java applets.

JavaScript’s Hasty Creation

In 1995, Brendan Eich created JavaScript in ten days for Netscape Navigator 2.0, initially as a Scheme-like language with a DOM interface. To counter Java applets, it adopted a C-like syntax and prototypal inheritance (inspired by Self), as classical inheritance wasn’t feasible in Scheme. Rendle humorously speculated on advising Eich to add static typing and classical inheritance, noting JavaScript’s roots in Fortran, ALGOL, Lisp, and others. Despite its rushed origins, JavaScript inherited a rich legacy, from Fortran’s syntax to Smalltalk’s object model.

The Legacy and Future of JavaScript

Rendle concluded by reflecting on JavaScript’s dominance, driven by its browser integration, and its ongoing evolution, with features like async/await (from C#) and proposed gradual typing. He dismissed languages like COBOL and Pascal for lacking influential contributions, crediting BASIC for inspiring programmers despite adding little to language design. JavaScript, a synthesis of 70 years of innovation, continues to evolve, shaped by decisions from 1955 to today, proving no language is immune to historical influence.

Hashtags: #JavaScript #ProgrammingHistory #MarkRendle #DevoxxBE2024

PostHeaderIcon [DevoxxUK2024] Is It (F)ake?! Image Classification with TensorFlow.js by Carly Richmond

Carly Richmond, a Principal Developer Advocate at Elastic, captivated the DevoxxUK2024 audience with her engaging exploration of image classification using TensorFlow.js. Inspired by her love for the Netflix show Is It Cake?, Carly embarked on a project to build a model distinguishing cakes disguised as everyday objects from their non-cake counterparts. Despite her self-professed lack of machine learning expertise, Carly’s journey through data gathering, pre-trained models, custom model development, and transfer learning offers a relatable and insightful narrative for developers venturing into AI-driven JavaScript applications.

Gathering and Preparing Data

Carly’s project begins with the critical task of data collection, a foundational step in machine learning. To source images of cakes resembling other objects, she leverages Playwright, a JavaScript-based automation framework, to scrape images from bakers’ websites and Instagram galleries. For non-cake images, Carly utilizes the Unsplash API, which provides royalty-free photos with a rate-limited free tier. She queries categories like reptiles, candles, and shoes to align with the deceptive cakes from the show. However, Carly acknowledges limitations, such as inadvertently including biscuits or company logos in the dataset, highlighting the challenges of ensuring data purity with a modest set of 367 cake and 174 non-cake images.

Exploring Pre-Trained Models

To avoid building a model from scratch, Carly initially experiments with TensorFlow.js’s pre-trained models, Coco SSD and MobileNet. Coco SSD, trained on the Common Objects in Context (COCO) dataset, excels in object detection, identifying bounding boxes and classifying objects like cakes with reasonable accuracy. MobileNet, designed for lightweight classification, struggles with Carly’s dataset, often misclassifying cakes as cups or ice cream due to visual similarities like frosting. CORS issues further complicate browser-based MobileNet deployment, prompting Carly to shift to a Node.js backend, where she converts images into tensors for processing. These experiences underscore the trade-offs between model complexity and practical deployment.

Building and Refining a Custom Model

Undeterred by initial setbacks, Carly ventures into crafting a custom convolutional neural network (CNN) using TensorFlow.js. She outlines the CNN’s structure, which includes convolution layers to extract features, pooling layers to reduce dimensionality, and a softmax activation for binary classification (cake vs. not cake). Despite her efforts, the model’s accuracy languishes at 48%, plagued by issues like tensor shape mismatches and premature tensor disposal. Carly candidly admits to errors, such as mislabeling cakes as non-cakes, illustrating the steep learning curve for non-experts. This section of her talk resonates with developers, emphasizing perseverance and the iterative nature of machine learning.

Leveraging Transfer Learning

Recognizing the limitations of her dataset and custom model, Carly pivots to transfer learning, using MobileNet’s feature vectors as a foundation. By adding a custom classification head with ReLU and softmax layers, she achieves a significant improvement, with accuracy reaching 100% by the third epoch and correctly classifying 319 cakes. While not perfect, this approach outperforms her custom model, demonstrating the power of leveraging pre-trained models for specialized tasks. Carly’s comparison of human performance—90% accuracy by the DevoxxUK audience versus her model’s results—adds a playful yet insightful dimension, highlighting the gap between human intuition and machine precision.

Links: