Recent Posts
Archives

Posts Tagged ‘JavaScript’

PostHeaderIcon [DotJs2024] How to Test Web Applications

Tracing the sinews of testing evolution unveils a saga of ingenuity amid constraints, where manual pokes birthed automated sentinels. Jessica Sachs, a product-minded frontend engineer at Ionic with a penchant for vintage tech, chronicled this odyssey at dotJS 2024. From St. Augustine’s cobblestone allure—America’s eldest city, founded 1565—she drew parallels to web dev’s storied paths, unearthing undocumented timelines via Wayback Machine dives and Twitter lore. Sachs’s quest: demystify the proliferation of test runners, revealing how historical exigencies—from CGI pains to Node’s ascent—shaped today’s arsenal, advocating patience for tools that integrate seamlessly into workflows.

Sachs ignited with a Twitter thread amassing 178 responses, crowdsourcing pre-2011 practices. The ’90s dawned with CGI scripts in C or Perl, rendering dynamic content via URL params—a nightmare for verification. Absent browsers, coders FTP’d to prod, editing vi in situ, then paraded to webmasters’ desks for eyeball tests on finicky monitors. Issues skewed infrastructural: network glitches, deployment fumbles, not logic lapses. Enter Selenium circa 2011, Sachs’s genesis as manual QA tapping iPads, automating browser puppeteering. Predecessors? Fragmented: HTTPUnit for server mocks, early Selenium precursors like Kantara for JavaScript injection.

The aughts splintered further. jQuery’s 2006 surge spawned QUnit; Yahoo UI birthed YUITest; Scriptaculous, Ruby-infused, shipped bespoke runners amid TDD fervor. Pushback mounted: velocity killers, JS’s ancillary role to backend logic. Breakthrough: 2007’s JS Test Driver, Mishko’s Java-forged Google tool, spawning browsers, watching files, reporting terminals—paving for Testacular (Karma’s cheeky forebear). PhantomJS enabled headless CI, universally loathed yet indispensable till Node. Sachs unearthed Ryan Florence’s GitHub plea rebranding Testacular to Karma, easing corporate qualms.

Node’s 2011 arrival unified: Jest, open-sourced by Facebook in 2014 (conceived 2011), tackled module transforms, fake DOMs for builds. Sachs lauded its webpack foresight, supplanting concatenation. Yet, sprawl persists: Bun, Deno, edge functions defy file systems; ESM, TypeScript confound. Vitest ascends, context-switching via jsdom, HappyDOM, browser modes, E2E orchestration—bundler-agnostic, coupling to transformers sans custom ones. Sachs’s epiphany: runners mirror environments; history’s lessons—manual sufficed for Android pre-automation—affirm: prioritize speed, workflow harmony. Novel tools demand forbearance; value accrues organically.

Sachs’s tapestry reminds: testing’s not punitive but enabler, evolving from ad-hoc to ecosystem symbiote, ensuring robustness amid flux.

Unearthing Testing’s Archaic Roots

Sachs’s archival foray exposed ’90s drudgery: CGI’s prod edits via vi, manual verifications on webmaster rigs, network woes trumping semantics. Selenium’s 2011 automation eclipsed this, but antecedents like HTTPUnit hinted at mocks. The 2000s fragmented—YUITest, QUnit tying to libs—yet JS Test Driver unified, birthing Karma’s headless era via PhantomJS, Node’s prelude.

The Node Era and Modern Convergence

Jest’s 2014 debut addressed builds, modules; Vitest now reigns, emulating DOMs diversely, launching browsers, integrating E2E. Sachs spotlighted bundlers as logic proxies, ESM/TS as Jest’s Achilles; Vitest’s flexibility heralds adaptability. Android’s manual heritage validates: tools must accelerate, not hinder—foster adoption through velocity.

Links:

PostHeaderIcon [DotJs2024] Thinking About Your Code: Push vs Pull

Navigating the currents of performant code demands a lens attuned to flow dynamics, where producers and consumers dance in tandem—or discord. Ben Lesh, a veteran of high-stakes web apps from Netflix’s infrastructure dashboards to RxJS stewardship, shared this paradigm at dotJS 2024. With roots in rendering millions of devices across North America’s bandwidth, Lesh distilled decades of collaboration with elite engineers into a quartet of concepts: producers, consumers, push, pull. These primitives illuminate code’s underbelly, spotlighting concurrency pitfalls, backpressure woes, and optimal primitives for JavaScript’s asynchronous tapestry.

Lesh’s entrée was a bespoke live demo: enlisting audience volunteer Jessica Sachs to juggle M&Ms, embodying production-consumption. Pull—Jessica grabbing at will—affords control but falters asynchronously; absent timely M&Ms, hands empty. Push—Lesh feeding sequentially—frees producers for factories but risks overload, manifesting backpressure as frantic consumption. Code mirrors this: a getValue() invocation pulls synchronously, assigning to a consumer like console.log; for loops iterate pulls from arrays. Yet, actors abound: functions produce, variables consume; callbacks push events, observables compose them.

JavaScript’s arsenal spans quadrants. Pure pull: functions and intervals yield eager values. Push: callbacks for one-offs, observables for streams—RxJS’s forte, enabling operators like map or mergeMap for event orchestration. Pull-then-push hybrids: promises (function returning deferred push) and async iterables (yielding promise-wrapped results), ideal for paced delivery via for await...of, mitigating backpressure in slow consumers. Push-then-pull inverts: signals—Ember computeds, Solid observables, Angular runes—notify changes, deferring reads until render. Lesh previewed TC39 signals: subscribe for pushes, get for pulls, birthing dependency graphs that lazy-compute, tracking granular ties for efficient diffing.

This framework unveils pathologies: thread lockups from unchecked pushes, concurrency clashes in nested callbacks. Lesh advocated scanning code for actors—spotting producers hidden in APIs—and matching primitives to intent. Pull suits sync simplicity; push excels in async firehoses; hybrids temper throughput; signals orchestrate reactive UIs. As frameworks like React lean on signals for controlled reads pre-render, developers gain foresight into bottlenecks, fostering resilient, scalable architectures.

Decoding Flow Primitives in JavaScript

Lesh partitioned primitives into a revealing matrix: pull for immediacy (functions pulling values), push for autonomy (observables dispatching relentlessly). Hybrids like promises bridge, returning handles for eventual pushes; async iterables extend, pacing via awaits. Signals, the push-pull hybrid, notify sans immediate computation—perfect for UI graphs where effects propagate selectively, as in Solid’s fine-grained reactivity or Angular’s zoned eschewal.

Navigating Backpressure and Optimization

Backpressure—producers overwhelming consumers—Lesh dramatized via M&M deluge, solvable by hybrids throttling intake. Signals mitigate via lazy evals: update signals, compute only on get, weaving dependency webs that prune cascades. Lesh urged: interrogate code’s flows—who pushes/pulls?—to preempt issues, leveraging RxJS for composition, signals for reactivity, ensuring apps hum under load.

Links:

PostHeaderIcon [DotJs2024] API Design is UI Design

In the intricate tapestry of software craftsmanship, the boundaries between visual interfaces and programmatic ones blur, revealing a unified discipline rooted in empathy and usability. Lea Verou, a luminary in web standards and W3C TAG member, delivered a revelatory session at dotJS 2024, asserting that API design mirrors UI design in every facet—from intuitiveness to error resilience. With a PhD from MIT focused on developer experience and stewardship of dozens of open-source projects, Verou dissected the pitfalls of APIs that frustrate and the principles that enchant, urging creators to treat code as an interface wielded by fellow humans.

Verou opened with a visceral anecdote: the SVG DOM’s labyrinthine quest to extract a circle’s radius, yielding not a crisp number but an SVGAnimatedLength riddled with baseVal, animVal, and unit-conversion methods—annoying even sans animations. This exemplar encapsulated her thesis: APIs, be they functions, classes, components, or native browser APIs, are user interfaces where developers are the users, and interactions manifest as keystrokes. Echoing Alan Kay’s maxim—”simple things should be easy, complex things possible”—she mapped it to a complexity plane: low-effort dots for trivial tasks, viable paths for sophistication. Usability tenets, from Google Calendar’s drag-and-drop simplicity to advanced recurrence rules, permeate both realms; DX is merely UX recast for code scribes.

Central to Verou’s discourse was user-centricity: APIs thrive when attuned to genuine needs, not theoretical purity. High-level use cases—like assembling IKEA furniture with a screwdriver—inform broad abstractions, while low-level ones—like screwing a wall anchor—demand primitives. She critiqued legacy DOM traversals burdened by redundant parent references, supplanted by modern APIs favoring single-truth sources. Components exemplify elegance: encapsulating dialog boilerplate into reusable units slashes cognitive load. Iterating isn’t prohibitive; ship high-level facades covering 80% of scenarios, layering primitives as demands surface—or vice versa, observing usage to scaffold abstractions. The Intl.DateTimeFormat API’s evolution—from vague toLocaleString to nuanced options yielding structured outputs—exemplifies this progressive disclosure, smoothing from casual to granular control.

Verou championed empirical validation: user testing, sans visuals, via representative tasks and think-aloud protocols. Five participants unearth 85% of issues; two halve them. Zoom suffices—no labs required. Dogfooding complements: prototype demos, draft docs, author tests pre-implementation, refining iteratively. Empathy crowns all: intuit users’ pains, infer principles organically. Tailwind’s rise signals CSS’s accessibility gaps; blame the medium, not the maker, and mend it. Verou’s clarion call: infuse humanity into APIs, easing burdens and amplifying creativity across the dev spectrum.

Usability Principles Across Interfaces

Verou wove Kay’s dictum into a visual quadrant, plotting task complexity against UI/API effort, advocating coverage of simple-easy and complex-possible quadrants. User needs—pain points, scenarios—drive this: distinguish macro goals from micro actions, ensuring APIs mirror real workflows. SVG’s unit obsessions ignored 90% of queries; streamlined getters would suffice. Progressive layers, as in date formatting’s escalating options, democratize power without overwhelming novices.

Empirical Refinement and Empathy

Testing APIs demands observation: task users, query struggles non-leadingly, affirm it’s the design under scrutiny. Verou debunked myths—engineers aren’t users; widespread misuse indicts the API. Dogfood rigorously: sketch code flows pre-build, iterate via docs and tests. Ultimate imperative: cultivate care—empathize with wielders’ contexts, yielding designs that intuit, adapt, and inspire.

Links:

PostHeaderIcon [DotJs2024] Generative UI: Bring your React Components to AI Today!

The fusion of artificial intelligence and frontend development is reshaping how we conceive interactive experiences, placing JavaScript engineers at the vanguard of this transformation. Malte Ubl, CTO at Vercel, captivated audiences at dotJS 2024 with a compelling exploration of Generative UI, a pivotal advancement in Vercel’s AI SDK. Originally hailing from Germany and now entrenched in Silicon Valley’s innovation hub, Ubl reflected on the serendipitous echoes of past tech eras—from CGI uploads via FTP to his own contributions like Whiz at Google—before pivoting to AI’s seismic impact. His message was unequivocal: frontend expertise isn’t obsolete in the AI surge; it’s indispensable, empowering developers to craft dynamic, context-aware interfaces that transcend textual exchanges.

Ubl framed the narrative around a paradigm shift from Software 1.0’s laborious machine learning to Software 2.0’s accessible, API-driven intelligence. Where once PhD-level Python tinkering dominated, today’s landscape favors TypeScript applications invoking large language models (LLMs) as services. Models have ballooned in scale and savvy, rendering fine-tuning optional and prompting paramount. This velocity—shipping products in days rather than years—democratizes AI development, yet disrupts traditional roles. Ubl’s optimism stems from a clear positioning: frontend developers as architects of human-AI symbiosis, leveraging React components to ground abstract prompts in tangible interactions.

Central to his demonstration was a conversational airline booking interface, where users query seat changes via natural language. Conventional AI might bombard with options like 14C or 19D, overwhelming without context. Generative UI elevates this: the LLM invokes React server components as functions, streaming a interactive seat map pre-highlighting viable window seats. Users manipulate the UI directly—selecting, visualizing availability—bypassing verbose back-and-forth. Ubl showcased the underlying simplicity: a standard React project with TypeScript files for boarding passes and seat maps, hot-module-reloading enabled, running locally. The magic unfolds via AI functions—React server components that embed client-side state, synced back to the LLM through an “AI state” mechanism. Selecting 19C triggers a callback: “User selected seat 19C,” enabling seamless continuations like checkout flows yielding digital boarding passes.

This isn’t mere novelty; Ubl underscored practical ramifications. End-user chatbots gain depth, support teams wield company-specific components for real-time adjustments, and search engines like the open-source Wary (a Perplexity analog) integrate existing product renderers for enriched results. Accessibility leaps forward too: retrofitting legacy sites with AI state turns static pages into voice-navigable experiences, empowering non-traditional input modalities. Ubl likened AI to a potent backend—API calls fetching not raw data, but rendered intelligence—amplifying human-computer dialogue beyond text. As models from OpenAI, Google Gemini, Anthropic’s Claude, and Mistral proliferate, frontend differentiation via intuitive UIs becomes the competitive edge, uplifting the stack’s user-facing stratum.

Ubl’s closing exhortation: embrace this disruption by viewing React components as AI-native building blocks. Vercel’s AI SDK examples offer starter chatbots primed for customization, accelerating prototyping. In a world where AI smarts escalate, frontend artisans—adept at state orchestration and visual storytelling—emerge as the revolution’s fulcrum, forging empathetic, efficient digital realms.

The Dawn of AI-Infused Interfaces

Ubl vividly contrasted archaic AI chats with generative prowess, using an airline scenario to highlight contextual rendering’s superiority. Prompts yield not lists, but explorable maps—streamed via server components—where selections feed back into the AI loop. This bidirectional flow, powered by AI state, ensures coherence, transforming passive queries into collaborative sessions. Ubl’s live demo, from flight selection to boarding pass issuance, revealed the unobtrusive elegance: plain React, no arcane setups, just LLM-orchestrated functions bridging intent and action.

Empowering Developers in the AI Era

Beyond demos, Ubl advocated for strategic adoption, spotlighting use cases like e-commerce search enhancements and accessibility overlays. Existing components slot into AI workflows effortlessly, while diverse models foster toolkit pluralism. The SDK’s documentation and examples lower barriers, inviting experimentation. Ubl’s thesis: as AI commoditizes logic, frontend’s artistry—crafting modality-agnostic interactions—secures its primacy, heralding an inclusive future where developers orchestrate intelligence with familiar tools.

Links:

PostHeaderIcon [DevoxxPL2022] Why is Everyone Laughing at JavaScript? Why All Are Wrong? • Michał Jawulski

At Devoxx Poland 2022, Michał Jawulski, a seasoned developer from Capgemini, delivered an engaging presentation that tackled the misconceptions surrounding JavaScript, a language often mocked through viral memes. Michał’s talk, rooted in his expertise and passion for software development, aimed to demystify JavaScript’s quirks, particularly its comparison and plus operator behaviors. By diving into the language’s official documentation, he provided clarity on why JavaScript behaves the way it does, challenging the audience to see beyond the humor and appreciate its logical underpinnings. His narrative approach not only educated but also invited developers to rethink their perceptions of JavaScript’s design.

Unraveling JavaScript’s Comparison Quirks

Michał began by addressing the infamous JavaScript memes that circulate online, often highlighting the language’s seemingly erratic comparison behaviors. He classified these memes into two primary categories: those related to comparison operators and those involving the plus sign operator. To understand these peculiarities, Michał turned to the ECMAScript specification, emphasizing that official documentation, though less accessible than resources like MDN, holds the key to JavaScript’s logic. He contrasted the ease of finding Java or C# documentation with the challenge of locating JavaScript’s official specification, which is often buried deep in search results and presented as a single, scroll-heavy page.

The core of Michał’s exploration was the distinction between JavaScript’s double equal (==) and triple equal (===) operators. He debunked the common interview response that the double equal operator ignores type checking. Instead, he explained that == does consider types but applies type coercion when they differ. For instance, when comparing null and undefined, == returns true due to their equivalence in this context. Similarly, when comparing non-numeric values, == attempts to convert them to numbers—true becomes 1, null becomes 0, and strings like "infinity" become the numeric Infinity. In contrast, the === operator is stricter, returning false if types differ, ensuring both type and value match. This systematic breakdown revealed that JavaScript’s comparison logic, while complex, is consistent and predictable when understood.

Decoding the Plus Operator’s Behavior

Beyond comparisons, Michał tackled the plus operator (+), which often fuels JavaScript memes due to its dual role in numeric addition and string concatenation. He explained that the plus operator first converts operands to primitive values. If either operand is a string, concatenation occurs; otherwise, both are converted to numbers for addition. For example, true + true results in 2, as both true values convert to 1. However, when an empty array ([]) is involved, it converts to an empty string (""), leading to concatenation results like [] + [] yielding "". Michał highlighted specific cases, such as [] + {} producing "[object Object]" in some environments, noting that certain behaviors, like those in Google Chrome, may vary due to implementation differences.

By walking through these examples, Michał demonstrated that JavaScript’s plus operator follows a clear algorithm, dispelling the notion of randomness. He argued that the humor in JavaScript memes stems from a lack of understanding of these rules. Developers who grasp the conversion logic can predict outcomes with confidence, turning seemingly bizarre results into logical conclusions. His analysis transformed the audience’s perspective, encouraging them to approach JavaScript with curiosity rather than skepticism.

Reframing JavaScript’s Reputation

Michał concluded by asserting that JavaScript’s quirks are not flaws but deliberate design choices rooted in its flexible type system. He urged developers to move beyond mocking the language and instead invest time in understanding its documentation. By doing so, they can harness JavaScript’s power effectively, especially in dynamic web applications. Michał’s talk was a call to action for developers to embrace JavaScript’s logic, fostering a deeper appreciation for its role in modern development. His personal touch—sharing his role at Capgemini and his passion for the English Premier League—added warmth to the technical discourse, making the session both informative and relatable.

Links:

PostHeaderIcon [NodeCongress2021] Demystifying Memory Leaks in JavaScript – Ruben Bridgewater

Unraveling the enigma of escalating heap usage transforms from arcane ritual to methodical pursuit under Ruben Bridgewater’s guidance. As principal software architect at Datadog and Node.js Technical Steering Committee member, Ruben demystifies leaks—unfreed allocations snowballing to OOM crashes or inflated bills—via V8’s innards and profiling arsenal.

Ruben invokes Wikipedia: leaks arise from mismanaged RAM, no longer needed yet unreclaimed, yielding upward trajectories on usage graphs versus steady baselines. JavaScript’s GC—mark-sweep for majors, scavenge for minors—orchestrates reclamation, yet closures, globals, or detached DOM snare objects in retention webs.

Profiling the Culprits

Chrome DevTools reigns: timelines chart allocations, heap snapshots freeze states for delta diffs—2.4MB spikes spotlight string hordes in func contexts. Ruben demos: inspect reveals var string chains, tracing to errant accumulators.

Clinic.js automates: clinic doctor flags leaks via flame graphs; heap-profiler pinpoints retainers. Production? APMs like Datadog monitor baselines, alerting deviations—avoid snapshots’ pauses therein.

Browser parity extends tooling: inspect Memory tab mirrors Node’s inspector.

Remediation Roadmaps

Ruben’s playbook: surveil via APMs, snapshot judiciously (controlled environs), diff deltas for deltas, excise roots—globals to WeakMaps, arrays to Sets. Data choices matter—primitives over objects; restarts as Hail Marys.

Ken Thompson’s quip—ditching code boosts productivity—caps Ruben’s ode to parsimony. Memory’s dual toll—fiscal, performative—demands preemption, yielding snappier, thriftier apps.

Links:

PostHeaderIcon [NodeCongress2021] Security Testing for JS Apps, Node Congress – Ryan Severns

Application security need not impede developer agility; instead, it can integrate seamlessly into workflows. Ryan Severns, co-founder of StackHawk, presents a streamlined approach to vulnerability detection in JavaScript ecosystems, leveraging automation to unearth issues pre-production.

StackHawk automates dynamic analysis against JS apps and APIs—REST, GraphQL—flagging SQL injections or data leaks via CI/CD scans. On pull requests, scans mimic attacks, surfacing flaws with request/response evidence, expediting triages.

Automating Scans with ZAP Foundations

Built atop OWASP ZAP, StackHawk configures effortlessly for Node.js stacks, scanning SPAs or backends sans code mods. Post-scan, dashboards highlight exploits, with remediation docs and Jira integrations deferring low-risks, respecting only novel threats.

Integrating into DevSecOps Pipelines

Ryan emphasizes workflow harmony: GitHub Actions triggers validate endpoints, blocking merges on criticals while queuing fixes. Free tiers invite experimentation, blending security into Node.js velocity without friction.

Links:

PostHeaderIcon [KotlinConf2019] Exploring the Power of Kotlin/JS

Sebastian Aigner, a developer advocate at JetBrains, captivated KotlinConf2019 with his deep dive into Kotlin/JS, the JavaScript target for Kotlin. With a passion for web development, Sebastian showcased how recent advancements make Kotlin/JS a compelling choice for building web applications. From streamlined tooling to seamless JavaScript interoperability, he outlined the current state and future potential of Kotlin/JS, inspiring both newcomers and seasoned developers to leverage Kotlin’s paradigms in the browser.

Simplifying Development with the New Gradle Plugin

Kotlin/JS has evolved significantly, with the new Kotlin/JS Gradle plugin emerging as the cornerstone for browser and Node.js development. Sebastian explained that this plugin unifies previously fragmented approaches, replacing deprecated plugins like kotlin2js and kotlin-frontend. Its uniform Gradle DSL simplifies project setup, offering sensible defaults for Webpack bundling without requiring extensive configuration. For developers transitioning to multi-platform projects, the plugin’s compatibility with the Kotlin multi-platform DSL minimizes changes, enabling seamless integration of additional targets. By automating JavaScript environment setup, including yarn and package.json, the plugin empowers Kotlin developers to focus on coding rather than managing complex JavaScript tooling.

Mastering Dependency Management with npm

The JavaScript ecosystem, with over a million npm packages, offers unparalleled flexibility, and Kotlin/JS integrates effortlessly with this vast library. Sebastian highlighted how the Gradle plugin manages npm dependencies directly, automatically updating package.json when dependencies like React or styled-components are added. This eliminates the need for separate JavaScript environment setup, saving time, especially on non-standard platforms like Windows. Developers can import Kotlin libraries (e.g., coroutines, serialization) alongside JavaScript packages, with Gradle handling the JavaScript-specific versions. This unified approach bridges the gap between Kotlin’s structured ecosystem and JavaScript’s dynamic world, making dependency management intuitive even for those new to JavaScript.

Bridging Kotlin and TypeScript with Dukat

Interoperating with JavaScript’s dynamic typing can be challenging, but Sebastian introduced Dukat, an experimental tool that converts TypeScript declaration files into Kotlin external declarations. By leveraging TypeScript’s de facto standard for type definitions, Dukat enables type-safe access to npm packages, such as left-pad or react-minimal-pie-chart. While manual external declarations require tedious annotation, Dukat automates this process, generating headers for packages with TypeScript support or community-contributed definitions. Sebastian encouraged early adoption to provide feedback, noting that Dukat already powers browser and Node.js API wrappers. This tool promises to simplify integration with JavaScript libraries, reducing the friction of crossing the static-dynamic typing divide.

Enhancing Testing and Debugging with Source Maps

Testing and debugging are critical for robust applications, and Kotlin/JS delivers with integrated tools. Sebastian demonstrated how the Gradle plugin supports platform-specific test runners like Karma, allowing tests to run across browsers (e.g., Firefox, headless Chrome). Source maps, automatically generated since Kotlin 1.3.60, provide detailed stack traces for Node.js and interactive debugging in browser DevTools. Developers can set breakpoints in Kotlin code, inspect variables, and trace errors directly in Chrome’s console, as shown in Sebastian’s pong game demo. Gradle test reports further enhance diagnostics, offering HTML-based insights into test failures, making Kotlin/JS development as robust as its JVM counterpart.

Optimizing with the IR Backend

The upcoming Intermediate Representation (IR) backend marks a significant leap for Kotlin/JS. Sebastian outlined its benefits, including aggressive code size optimizations through dead code elimination. Unlike the current backend, which may ship the entire standard library, the IR backend, combined with Google Closure Compiler, reduces zipped file sizes dramatically—down to 30 KB from 3.9 MB in some cases. Faster compilation speeds, especially for incremental builds, enhance developer productivity, particularly in continuous build scenarios with Webpack’s dev server. The IR backend also supports platform-agnostic compiler plugins, simplifying multi-platform development. Sebastian noted that pre-alpha IR support in Kotlin 1.3.70 requires manual exports due to its closed-world assumption, urging developers to explore early releases.

Looking Ahead: WebAssembly and Framework Support

Sebastian concluded with a glimpse into Kotlin/JS’s future, highlighting potential support for ECMAScript 6 modules and frameworks like Angular and Vue.js. While JetBrains provides React wrappers, extending first-class support to other frameworks requires addressing their unique tooling and compilers. The IR backend also opens doors to WebAssembly, enabling Kotlin to target browsers more efficiently. Though no timelines were promised, these explorations reflect JetBrains’ commitment to aligning Kotlin/JS with modern web trends. Sebastian’s call to action—trying the Code Quiz app at the Kotlin booth and contributing to Dukat—emphasized community involvement in shaping Kotlin/JS’s evolution.

Links:

PostHeaderIcon [KotlinConf2019] Building Progressive Web Apps in Kotlin: A New Frontier with Erik Hellman

The landscape of web development has traditionally been dominated by JavaScript and its ecosystem of tools and frameworks. However, with Kotlin’s growing versatility, particularly its Kotlin/JS capabilities, new avenues are opening up for developers who prefer Kotlin’s syntax and features. Erik Hellman, an experienced software consultant with a deep background in various programming languages, explored this exciting intersection at KotlinConf 2019. His session, “Building Progressive Web Apps in Kotlin,” introduced how Kotlin, combined with its JavaScript support, could be used to create modern web applications, also known as Progressive Web Apps (PWAs).

Erik Hellman’s talk aimed to show developers how they could leverage their Kotlin knowledge to build PWAs, potentially using popular JavaScript frameworks like React, Vue.js, or LitElement through Kotlin wrappers or directly with Kotlin/JS. This approach offers an alternative for those who find Kotlin more aligned with their development style than TypeScript or plain JavaScript, or for teams looking to unify their technology stack around Kotlin.

Kotlin/JS: Bridging Kotlin to the Web

At the heart of building web applications with Kotlin is Kotlin/JS, which allows Kotlin code to be compiled (or “transpiled”) into JavaScript. Erik Hellman explained the fundamentals of Kotlin/JS, including how it maps Kotlin concepts to their JavaScript equivalents and enables interoperability with existing JavaScript libraries and browser APIs. This capability is crucial, as it allows Kotlin developers to tap into the vast JavaScript ecosystem while writing code in a language they are comfortable and productive with.

The session would have covered how to set up a Kotlin/JS project, manage dependencies, and structure code for web development. Erik might have also discussed the benefits of using Kotlin for web development, such as its strong type system, null safety, and conciseness, which can lead to more robust and maintainable web applications compared to traditional JavaScript development. The focus was on providing a pathway for Kotlin enthusiasts to extend their skills into the PWA domain.

Progressive Web Apps: Enhancing the Web Experience

Progressive Web Apps (PWAs) represent an evolution of web applications, aiming to provide a user experience similar to native mobile apps. Key features of PWAs include offline capabilities (through service workers), installability on user devices, push notifications, and fast performance. Erik Hellman’s talk would have explored how these PWA characteristics can be implemented using Kotlin/JS.

A significant part of building PWAs involves working with service workers for caching and offline support, and web app manifests for installability. Erik demonstrated how to write service worker logic in Kotlin and manage the manifest file within a Kotlin/JS project. He might have also touched upon techniques for optimizing performance and ensuring a smooth user experience, which are critical aspects of successful PWAs. The overall goal was to equip Kotlin developers with the knowledge to build modern, engaging web experiences that leverage the latest web platform features.

Current State and Future Promise

During his 2019 presentation, Erik Hellman acknowledged that while Kotlin/JS was powerful, the tooling and ecosystem were still maturing, particularly around areas like code splitting for service workers. He noted that finding help and up-to-date information sometimes required tapping into the Kotlin community, such as the official Slack channel.

Despite these challenges, he conveyed a sense of optimism, stating that Kotlin/JS looked “really really promising” as an alternative for web development, especially for projects where Kotlin was already in use for other components (like backend or mobile). He suggested that for many use cases, Kotlin/JS was already a viable option. His talk concluded by pointing towards the continued development and improvement of Kotlin/JS, anticipating it would become an even more compelling choice for building PWAs in the future, offering a robust and enjoyable development experience for Kotlin aficionados venturing into the web.

Links:

PostHeaderIcon [DevoxxFR 2019] Back to Basics: Stop Wasting Time with Dates

At Devoxx France 2019, Frédéric Camblor, a web developer at 4SH in Bordeaux, delivered an insightful session on mastering date and time handling in software applications. Drawing from years of noting real-world issues in a notebook, Frédéric aimed to equip developers with the right questions to ask when working with dates, ensuring they avoid common pitfalls like time zone mismatches, daylight saving time (DST) quirks, and leap seconds.

Understanding Time Fundamentals

Frédéric began by exploring the historical context of time measurement, contrasting ancient solar-based “true time” with modern standardized systems. He introduced Greenwich Mean Time (GMT), now deprecated in favor of Coordinated Universal Time (UTC), which is based on International Atomic Time. UTC, defined by the highly regular oscillations of cesium-133 atoms (9,192,631,770 per second), is geopolitically agnostic, free from DST or seasonal shifts, with its epoch set at January 1, 1970, 00:00:00 Greenwich time.

The distinction between GMT and UTC lies in the irregularity of Earth’s rotation, affected by tidal forces and earthquakes. To align astronomical time (UT1) with atomic time, leap seconds are introduced every six months by the International Earth Rotation and Reference Systems Service (IERS). In Java, these leap seconds are smoothed over the last 1,000 seconds of June or December, making them transparent to developers. Frédéric emphasized the role of the Network Time Protocol (NTP), which synchronizes computer clocks to atomic time via a global network of root nodes, ensuring sub-second accuracy despite local quartz oscillator drift.

Time Representations in Software

Frédéric outlined three key time representations developers encounter: timestamps, ISO 8601 datetimes, and local dates/times. Timestamps, the simplest, count seconds or milliseconds since the 1970 epoch but face limitations, such as the 2038 overflow issue on 32-bit systems (though mitigated in Java). ISO 8601 datetimes (e.g., 2019-04-18T12:00:00+01:00) offer human-readable precision with time zone offsets, enhancing clarity over raw timestamps. Local dates/times, however, are complex, often lacking explicit time zone or DST context, leading to ambiguities in scenarios like recurring meetings.

Each representation has trade-offs. Timestamps are precise but opaque, ISO 8601 is readable but requires parsing, and local times carry implicit assumptions that can cause bugs if not clarified. Frédéric urged developers to choose representations thoughtfully based on application needs.

Time zones, defined by the IANA database, are geopolitical regions with uniform time rules, distinct from time zone offsets (e.g., UTC+1). Frédéric clarified that a time zone like Europe/Paris can yield different offsets (UTC+1 or UTC+2) depending on DST, which requires a time zone table to resolve. These tables, updated frequently (e.g., nine releases in 2018), reflect geopolitical changes, such as Russia’s abrupt time zone shifts or the EU’s 2018 consultation to abolish DST by 2023. Frédéric highlighted the importance of updating time zone data in systems like Java (via JRE updates or TZUpdater), MySQL, or Node.js to avoid outdated rules.

DST introduces further complexity, creating “local time gaps” during spring transitions (e.g., 2:00–3:00 AM doesn’t exist) and overlaps in fall (e.g., 2:00–3:00 AM occurs twice). Libraries handle these differently: Moment.js adjusts invalid times, while Java throws exceptions. Frédéric warned against scheduling tasks like CRON jobs at local times prone to DST shifts (e.g., 2:30 AM), recommending UTC-based scheduling to avoid missed or duplicated executions.

Common Pitfalls and Misconceptions

Frédéric debunked several myths, such as “a day is always 24 hours” or “comparing dates is simple.” DST can result in 23- or 25-hour days, and leap years (every four years, except centurial years not divisible by 400) add complexity. For instance, 2000 was a leap year, but 2100 won’t be. Comparing dates requires distinguishing between equality (same moment) and identity (same time zone), as Java’s equals() and isEqual() methods behave differently.

JavaScript’s Date object was singled out for its flaws, including inconsistent parsing (dashes vs. slashes shift time zones), zero-based months, and unreliable handling of pre-1970 dates. Frédéric recommended using libraries like Moment.js, Moment-timezone, or Luxon to mitigate these issues. He also highlighted edge cases, such as the non-existent December 30, 2011, in Samoa due to a time zone shift, which can break calendar applications.

Best Practices for Robust Date Handling

Frédéric shared practical strategies drawn from real-world experience. Servers and databases should operate in UTC to avoid DST issues and expose conversion bugs when client and server time zones differ. For searches involving local dates (e.g., retrieving messages by date), he advocated defining a date range (e.g., 00:00–23:59 in the user’s time zone) rather than a single date to account for implicit time zone assumptions. Storing future dates requires capturing the user’s time zone to handle potential rule changes.

For time-only patterns (e.g., recurring 3:00 PM meetings), storing the user’s time zone is critical to resolve DST ambiguities. Frédéric advised against storing times in datetime fields (e.g., as 1970-01-01T15:00:00), recommending string storage with time zone metadata. For date-only patterns like birthdays, using dedicated data structures prevents inappropriate operations, and storing at 12:00 UTC minimizes time zone shift bugs. Finally, he cautioned against local datetimes without time zones, as they cannot be reliably placed on a timeline.

Frédéric concluded by urging developers to question assumptions, update time zone data, and use appropriate time scales. His engaging talk, blending humor, history, and hard-earned lessons, left attendees ready to tackle date and time challenges with confidence.

Hashtags: #DateTime #TimeZones #DST #ISO8601 #UTC #DevoxxFR2019 #FrédéricCamblor #4SH #Java #JavaScript