General

Principal Software Engineer @ Just Eat Takeaway. iOS Infrastructure Engineer. Based in London.

Scalable Continuous Integration for iOS

  • CI
  • mobile
  • iOS
  • AWS
  • macOS

How Just Eat Takeaway.com leverage AWS, Packer, Terraform and GitHub Actions to manage a CI stack of macOS runners.

Originally published on the Just Eat Takeaway Engineering Blog. How Just Eat Takeaway.com leverage AWS, Packer, Terraform and GitHub Actions to manage a CI stack of macOS runners. Problem At Just Eat Takeaway.com (JET), our journey through continuous integration (CI) reflects a landscape of innovation and adaptation. Historically, JET’s multiple iOS teams operated independently, each employing their distinct CI solutions. The original Just Eat iOS and Android teams had pioneered an in-house CI solution anchored in Jenkins. This setup, detailed in our 2021 article, served as the backbone of our CI practices up until 2020. It was during this period that the iOS team initiated a pivotal migration: moving from in-house Mac Pros and Mac Minis to AWS EC2 macOS instances. Fast forward to 2023, a significant transition occurred within our Continuous Delivery Engineering (CDE) Platform Engineering team. The decision to adopt GitHub Actions company-wide has marked the end of our reliance on Jenkins while other teams are in the process of migrating away from solutions such as CircleCI and GitLab CI. This transition represented a fundamental shift in our CI philosophy. By moving away from Jenkins, we eliminated the need to maintain an instance for the Jenkins server and the complexities of managing how agents connected to it. Our focus then shifted to transforming our Jenkins pipelines into GitHub Actions workflows. This transformation extended beyond mere tool adoption. Our primary goal was to ensure that our macOS instances were not only scalable but also configured in code. We therefore enhanced our global CI practices and set standards across the entire company. Desired state of CI As we embarked on our journey to refine and elevate our CI process, we envisioned a state-of-the-art CI system. Our goals were ambitious yet clear, focusing on scalability, automation, and efficiency. At the time of implementing the system, no other player in the industry seemed to have implemented the complete solution we envisioned. Below is a summary of our desired CI state: Instance setup in code: One primary objective was to enable the definition of the setup of the instances entirely in code. This includes specifying macOS version, Xcode version, Ruby version, and other crucial configurations. For this purpose, the HashiCorp tool Packer, emerged once again as an ideal solution, offering the flexibility and precision we required. IaC (Infrastructure as Code) for macOS instances: To define the infrastructure of our fleet of macOS instances, we leaned towards Terraform, another HashiCorp tool. Terraform provided us with the capability to not only deploy but also to scale and migrate our infrastructure seamlessly, crucially maintaining its state. Auto and Manual Scaling: We wanted the ability to dynamically create CI runners based on demand, ensuring that resources were optimally utilized and available when needed. To optimize resource utilization, especially during off-peak hours, we desired an autoscaling feature. Scaling down our CI runners on weekends when developer activity is minimal was critical to be cost-effective. Automated Connection to GitHub Actions: We aimed for the instances to automatically connect to GitHub Actions as runners upon deployment. This automation was crucial in eliminating manual interventions via SSH or VNC. Multi-Team Use: Our vision included CI runners that could be easily used by multiple teams across different time zones. This would not only maximize the utility of our infrastructure but also encourage reuse and standardization. Centralized Management via GitHub Actions: To further streamline our CI processes, we intended to run all tasks through GitHub Actions workflows. This approach would allow the teams to self-serve and alleviate the need for developers to use Docker or maintain local environments. Getting to the desired state was a journey that presented multiple challenges and constant adjustments to make sure we could migrate smoothly to a new system. Instance setup in code We implemented the desired configuration with Packer leveraging a number of Shell Provisioners and variables to configure the instance. Here are some of the configuration steps: Set user password (to allow remote desktop access) Resize the partition to use all the space available on the EBS volume Start the Apple Remote Desktop agent and enable remote desktop access Update Brew & Install Brew packages Install CloudWatch agent Install rbenv/Ruby/bundler Install Xcode versions Install GitHub Actions actions-runner Copy scripts to connect to GitHub Actions as a runner Copy daemon to start the GitHub Actions self-hosted runner as a service Set macos-init modules to perform provisioning of the first launch While the steps above are naturally configuration steps to perform when creating the AMI, the macos-init modules include steps to perform once the instance becomes available. The create_ami workflow accepts inputs that are eventually passed to Packer to generate the AMI. packer build \ --var ami_name_prefix=${{ env.AMI_NAME_PREFIX }} \ --var region=${{ env.REGION }} \ --var subnet_id=${{ env.SUBNET_ID }} \ --var vpc_id=${{ env.VPC_ID }} \ --var root_volume_size_gb=${{ env.ROOT_VOLUME_SIZE_GB }} \ --var macos_version=${{ inputs.macos-version}} \ --var ruby_version=${{ inputs.ruby-version }} \ --var xcode_versions='${{ steps.parse-xcode-versions.outputs.list }}' \ --var gha_version=${{ inputs.gha-version}} \ bare-metal-runner.pkr.hcl Different teams often use different versions of software, like Xcode. To accommodate this, we permit multiple versions to be installed on the same instance. The choice of which version to use is then determined within the GitHub Actions workflows. The seamless generation of AMIs has proven to be a significant enabler. For example, when Xcode 15.1 was released, we executed this workflow the same evening. In just over two hours, we had an AMI ready to deploy all the runners (it usually takes 70–100 minutes for a macOS AMI with 400GB of EBS volume to become ready after creation). This efficiency enabled our teams to use the new Xcode version just a few hours after its release. IaC (Infrastructure as Code) for macOS instances Initially, we used distinct Terraform modules for each instance to facilitate the deployment and decommissioning of each one. Given the high cost of EC2 Mac instances, we managed this process with caution, carefully balancing host usage while also being mindful of the 24-hour minimum allocation time. We ultimately ended up using Terraform to define a single infrastructure (i.e. a single Terraform module) defining resources such as: aws_key_pair, aws_instance, aws_ami aws_security_group, aws_security_group_rule aws_secretsmanager_secret aws_vpc, aws_subnet aws_cloudwatch_metric_alarm aws_sns_topic, aws_sns_topic_subscription aws_iam_role, aws_iam_policy, aws_iam_role_policy_attachment, aws_iam_instance_profile A crucial part was to use count in aws_instance, setting the value of a variable passed in from deploy_infra workflow. Terraform performs the necessary scaling upon changing the value. We have implemented a workflow to perform Terraform apply and destroy commands for the infrastructure. Only the AMI and the number of instances are required as inputs. terraform ${{ inputs.command }} \ --var ami_name=${{ inputs.ami-name }} \ --var fleet_size=${{ inputs.fleet-size }} \ --auto-approve Using the name of the AMI instead of the ID allows us to use the most recent one that was generated, useful in case of name clashes. variable "ami_name" { type = string } variable "fleet_size" { type = number } data "aws_ami" "bare_metal_gha_runner" { most_recent = true filter { name = "name" values = ["${var.ami_name}"] } ... } resource "aws_instance" "bare_metal" { count = var.fleet_size ami = data.aws_ami.bare_metal_gha_runner.id instance_type = "mac2.metal" tenancy = "host" key_name = aws_key_pair.bare_metal.key_name ... } Instead of maintaining multiple CI instances with varying software configurations, we concluded that it’s simpler and more efficient to have a single, standardised setup. While teams still have the option to create and deploy their unique setups, a smaller, unified system allows for easier support by a single global configuration. Auto and Manual Scaling The deploy_infra workflow allows us to scale on demand but it doesn’t release the underlying dedicated hosts which are the resources that are ultimately billed. The autoscaling solution provided by AWS is great for VMs but gets sensibly more complex when actioned on dedicated hosts. Auto Scaling groups on macOS instances would require a Custom Managed License, a Host Resource Group and, of course, a Launch Template. Using only AWS services appears to be a lot of work to pull things together and the result wouldn’t allow for automatic release of the dedicated hosts. AirBnb mention in their Flexible Continuous Integration for iOS article that an internal scaling service was implemented: An internal scaling service manages the desired capacity of each environment’s Auto Scaling group. Some articles explain how to set up Auto Scaling groups for mac instances (see 1 and 2) but after careful consideration, we agreed that implementing a simple scaling service via GitHub Actions (GHA) was the easiest and most maintainable solution. We implemented 2 GHA workflows to fully automate the weekend autoscaling: Upscaling workflow to n, triggered at a specific time at the beginning of the working week Downscaling workflow to 1, triggered at a specific time at the beginning of the weekend We retain the capability for manual scaling, which is essential for situations where we need to scale down, such as on bank holidays, or scale up, like on release cut days, when activity typically exceeds the usual levels. Additionally, we have implemented a workflow that runs multiple times a day and tries to release all available hosts without an instance attached. This step lifts us from the burden of having to remember to release the hosts. Dedicated hosts take up to 110 minutes to move from the Pending to the Available state due to the scrubbing workflow performed by AWS. Manual scaling can be executed between the times the autoscaling workflows are triggered and they must be resilient to unexpected statuses of the infrastructure, which thankfully Terraform takes care of. Both down and upscaling are covered in the following flowchart: The autoscaling values are defined as configuration variables in the repo settings: It usually takes ~8 minutes for an EC2 mac2.metal instance to become reachable after creation, meaning that we can redeploy the entire infrastructure very quickly. Automated Connection to GitHub Actions We provide some user data when deploying the instances. resource "aws_instance" "bare_metal" { ami = data.aws_ami.bare_metal_gha_runner.id count = var.fleet_size ... user_data = <<EOF { "github_enterprise": "<GHE_ENTERPRISE_NAME>", "github_pat_secret_manager_arn": ${data.aws_secretsmanager_secret_version.ghe_pat.arn}, "github_url": "<GHE_ENTERPRISE_URL>", "runner_group": "CI-MobileTeams", "runner_name": "bare-metal-runner-${count.index + 1}" } EOF The user data is stored in a specific folder by macos-init and we implement a module to copy the content to ~/actions-runner-config.json. ### Group 10 ### [[Module]] Name = "Create actions-runner-config.json from userdata" PriorityGroup = 10 RunPerInstance = true FatalOnError = false [Module.Command] Cmd = ["/bin/zsh", "-c", 'instanceId="$(curl http://169.254.169.254/latest/meta-data/instance-id)"; if [[ ! -z $instanceId ]]; then cp /usr/local/aws/ec2-macos-init/instances/$instanceId/userdata ~/actions-runner-config.json; fi'] RunAsUser = "ec2-user" which is in turn used by the configure_runner.sh script to configure the GitHub Actions runner. #!/bin/bash GITHUB_ENTERPRISE=$(cat $HOME/actions-runner-config.json | jq -r .github_enterprise) GITHUB_PAT_SECRET_MANAGER_ARN=$(cat $HOME/actions-runner-config.json | jq -r .github_pat_secret_manager_arn) GITHUB_PAT=$(aws secretsmanager get-secret-value --secret-id $GITHUB_PAT_SECRET_MANAGER_ARN | jq -r .SecretString) GITHUB_URL=$(cat $HOME/actions-runner-config.json | jq -r .github_url) RUNNER_GROUP=$(cat $HOME/actions-runner-config.json | jq -r .runner_group) RUNNER_NAME=$(cat $HOME/actions-runner-config.json | jq -r .runner_name) RUNNER_JOIN_TOKEN=` curl -L \ -X POST \ -H "Accept: application/vnd.github+json" \ -H "Authorization: Bearer $GITHUB_PAT"\ $GITHUB_URL/api/v3/enterprises/$GITHUB_ENTERPRISE/actions/runners/registration-token | jq -r '.token'` MACOS_VERSION=`sw_vers -productVersion` XCODE_VERSIONS=`find /Applications -type d -name "Xcode-*" -maxdepth 1 \ -exec basename {} \; \ | tr '\n' ',' \ | sed 's/,$/\n/' \ | sed 's/.app//g'` $HOME/actions-runner/config.sh \ --unattended \ --url $GITHUB_URL/enterprises/$GITHUB_ENTERPRISE \ --token $RUNNER_JOIN_TOKEN \ --runnergroup $RUNNER_GROUP \ --labels ec2,bare-metal,$RUNNER_NAME,macOS-$MACOS_VERSION,$XCODE_VERSIONS \ --name $RUNNER_NAME \ --replace The above script is run by a macos-init module. ### Group 11 ### [[Module]] Name = "Configure the GHA runner" PriorityGroup = 11 RunPerInstance = true FatalOnError = false [Module.Command] Cmd = ["/bin/zsh", "-c", "/Users/ec2-user/configure_runner.sh"] RunAsUser = "ec2-user" The GitHub documentation states that it’s possible to create a customized service starting from a provided template. It took some research and various attempts to find the right configuration that allows the connection without having to log in in the UI (over VNC) which would represent a blocker for a complete automation of the deployment. We believe that the single person who managed to get this right is Sébastien Stormacq who provided the correct solution. The connection to GHA can be completed with 2 more modules that install the runner as a service and load the custom daemon. ### Group 12 ### [[Module]] Name = "Run the self-hosted runner application as a service" PriorityGroup = 12 RunPerInstance = true FatalOnError = false [Module.Command] Cmd = ["/bin/zsh", "-c", "cd /Users/ec2-user/actions-runner && ./svc.sh install"] RunAsUser = "ec2-user" ### Group 13 ### [[Module]] Name = "Launch actions runner daemon" PriorityGroup = 13 RunPerInstance = true FatalOnError = false [Module.Command] Cmd = ["sudo", "/bin/launchctl", "load", "/Library/LaunchDaemons/com.justeattakeaway.actions-runner-service.plist"] RunAsUser = "ec2-user" Using a daemon instead of an agent (see Creating Launch Daemons and Agents), doesn’t require us to set up any auto-login which on macOS is a bit of a tricky procedure and is best avoided also for security reasons. The following is the content of the daemon for completeness. <?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> <plist version="1.0"> <dict> <key>Label</key> <string>com.justeattakeaway.actions-runner-service</string> <key>ProgramArguments</key> <array> <string>/Users/ec2-user/actions-runner/runsvc.sh</string> </array> <key>UserName</key> <string>ec2-user</string> <key>GroupName</key> <string>staff</string> <key>WorkingDirectory</key> <string>/Users/ec2-user/actions-runner</string> <key>RunAtLoad</key> <true/> <key>StandardOutPath</key> <string>/Users/ec2-user/Library/Logs/com.justeattakeaway.actions-runner-service/stdout.log</string> <key>StandardErrorPath</key> <string>/Users/ec2-user/Library/Logs/com.justeattakeaway.actions-runner-service/stderr.log</string> <key>EnvironmentVariables</key> <dict> <key>ACTIONS_RUNNER_SVC</key> <string>1</string> </dict> <key>ProcessType</key> <string>Interactive</string> <key>SessionCreate</key> <true/> </dict> </plist> Not long after the deployment, all the steps above are executed and we can appreciate the runners appearing as connected. Multi-Team Use We start the downscaling at 11:59 PM on Fridays and start the upscaling at 6:00 AM on Mondays. These times have been chosen in a way that guarantees a level of service to teams in the UK, the Netherlands (GMT+1) and Canada (Winnipeg is on GMT-6) accounting for BST (British Summer Time) and DST (Daylight Saving Time) too. Times are defined in UTC in the GHA workflow triggers and the local time of the runner is not taken into account. Since the instances are used to build multiple projects and tools owned by different teams, one problem we faced was that instances could get compromised if workflows included unsafe steps (e.g. modifications to global configurations). GitHub Actions has a documentation page about Hardening self-hosted runners specifically stating: Self-hosted runners for GitHub do not have guarantees around running in ephemeral clean virtual machines, and can be persistently compromised by untrusted code in a workflow. We try to combat such potential problems by educating people on how to craft workflows and rely on the quick redeployment of the stack should the instances break. We also run scripts before and after each job to ensure that instances can be reused as much as possible. This includes actions like deleting the simulators’ content, derived data, caches and archives. Centralized Management via GitHub Actions The macOS runners stack is defined in a dedicated macOS-runners repository. We implemented GHA workflows to cover the use cases that allow teams to self-serve: create macOS AMI deploy CI downscale for the weekend* upscale for the working week* release unused hosts* * run without inputs and on a scheduled trigger The runners running the jobs in this repo are small t2.micro Linux instances and come with the AWSCLI installed. An IAM instance role with the correct policies is used to make sure that aws ec2 commands allocate-hosts, describe-hosts and release-hosts could execute and we used jq to parse the API responses. A note on VM runners In this article, we discussed how we’ve used bare metal instances as runners. We have spent a considerable amount of time investigating how we could leverage the Virtualization framework provided by Apple to create virtual machines via Tart. If you’ve grasped the complexity of crafting a CI system of runners on bare metal instances, you can understand that introducing VMs makes the setup sensibly more convoluted which would be best discussed in a separate article. While a setup with Tart VMs has been implemented, we realised that it’s not performant enough to be put to use. Using VMs, the number of runners would double but we preferred to have native performance as the slowdown is over 40% compared to bare metal. Moreover, when it comes to running heavy UI test suites like ours, tests became too flaky. Testing the VMs, we also realised that the standard values of Throughput and IOPS on the EBS volume didn’t seem to be enough and caused disk congestion resulting in an unacceptable slowdown in performance. Here is a quick summary of the setup and the challenges we have faced. Virtual runners require 2 images: one for the VMs (tart) and one for the host (AMI). We use Packer to create VM images (Vanilla, Base, IDE, Tools) with the software required based on the templates provided by Tart and we store the OCI-compliant images on ECR. We create these images on CI with dedicated workflows similar to the one described earlier for bare metal but, in this case, macOS runners (instead of Linux) are required as publishing to ECR is done with tart which runs on macOS. Extra policies are required on the instance role to allow the runner to push to ECR (using temporary_iam_instance_profile_policy_document in Packer’s Amazon EBS). Apple set a limit to the number of VMs that can be run on an instance to 2, which would allow to double the size of the fleet of runners. Creating AMIs hosting 2 VMs is done with Packer and steps include cloning the image from ECR and configuring macos-init modules to run daemons to run the VMs via Tart. Deploying a virtual CI infrastructure is identical to what has already been described for bare metal. Connecting to and interfacing with the VMs happens from within the host. Opening SSH and especially VNC sessions from within the bare metal instances can be very confusing. The version of macOS on the host and the one on the VMs could differ. The version used on the host must be provided with an AMI by AWS, while the version used on the VMs is provided by Apple in IPSW files (see ipsw.me). The GHA runners run on the VMs meaning that the host won’t require Xcode installed nor any other software used by the workflows. VMs don’t allow for provisioning meaning we have to share configurations with the VMs via shared folders on the host with the — dir flag which causes extra setup complexity. VMs can’t easily run the GHA runner as a service. The svc script requires the runner to be configured first, an operation that cannot be done during the provisioning of the host. We therefore need to implement an agent ourselves to configure and connect the runner in a single script. To have UI access (a-la VNC) to the VMs, it’s first required to stop the VMs and then run them without the --no-graphics flag. At the time of writing, copy-pasting won’t work even if using the --vnc or --vnc-experimental flags. Tartelet is a macOS app on top of Tart that allows to manage multiple GitHub Actions runners in ephemeral environments on a single host machine. We didn’t consider it to avoid relying on too much third-party software and because it doesn’t have yet GitHub Enterprise support. Worth noting that the Tart team worked on an orchestration solution named Orchard that seems to be in its initial stage. Conclusion In 2023 we have revamped and globalised our approach to CI. We have migrated from Jenkins to GitHub Actions as the CI/CD solution of choice for the whole group and have profoundly optimised and improved our pipelines introducing a greater level of job parallelisation. We have implemented a brand new scalable setup for bare metal macOS runners leveraging the HashiCorp tools Packer and Terraform. We have also implemented a setup based on Tart virtual machines. We have increased the size of our iOS team over the past few years, now including more than 40 developers, and still managed to be successful with only 5 bare metal instances on average, which is a clear statement of how performant and optimised our setup is. We have extended the capabilities of our Internal Developer Platform with a globalised approach to provide macOS runners; we feel that this setup will stand the test of time and serve well various teams across JET for years to come.

The idea of a Fastlane replacement

    Prelude

    Fastlane is widely used by iOS teams all around the world. It became the standard de facto to automate common tasks such as building apps, running tests, and uploading builds to App Store Connect. Fastlane has been recently moved under the Mobile Native Foundation which is amazing as Google

    Prelude Fastlane is widely used by iOS teams all around the world. It became the standard de facto to automate common tasks such as building apps, running tests, and uploading builds to App Store Connect. Fastlane has been recently moved under the Mobile Native Foundation which is amazing as Google wasn't actively maintaining the project. At Just Eat Takeaway, we have implemented an extensive number of custom lanes to perform domain-specific tasks and used them from our CI. The major problem with Fastlane is that it's written in Ruby. When it was born, using Ruby was a sound choice but iOS developers are not necessarily familiar with such language which represents a barrier to contributing and writing lanes. While Fastlane.swift, a version of Fastlane in Swift, has been in beta for years, it's not a rewrite in Swift but rather a "solution on top" meaning that developers and CI systems still have to rely on Ruby, install related software (rbenv or rvm) and most likely maintain a Gemfile. The average iOS dev knows well that Ruby environments are a pain to deal with and have caused an infinite number of headaches. In recent years, Apple has introduced technologies that would enable a replacement of Fastlane using Swift: Swift Package Manager (SPM) Swift Argument Parser (SAP) Being myself a big fan of CLI tools written in Swift, I soon started maturing the idea of a Fastlane rewrite in Swift in early 2022. I circulated the idea with friends and colleagues for months and the sentiment was clear: it's time for a fresh simil-Fastlane tool written in Swift. Journey Towards the end of 2022, I was determined to start this project. I teamed up with 2 iOS devs (not working at Just Eat Takeaway) and we started working on a design. I was keen on calling this project "Swiftlane" but the preference seemed to be for the name "Interstellar" which was eventually shortened into "Stellar". Fastlane has the concept of Actions and I instinctively thought that in Swift-land, they could take the form of SPM packages. This would make Stellar a modular system with pluggable components. For example, consider the Scan action in Fastlane. It could be a package that solely solves the same problem around testing. My goal was not to implement the plethora of existing Fastlane actions but rather to create a system that allows plugging in any package building on macOS. A sound design of such system was crucial. The Stellar ecosystem I had in mind was composed of 4 parts: Actions Actions are the basic building blocks of the ecosystem. They are packages that define a library product. An action can do anything, from taking care of build tasks to integrating with GitHub. Actions are independent packages that have no knowledge of the Stellar system, which treats them as pluggable components to create higher abstractions. Ideally, actions should expose an executable product (the CLI tool) using SAP calling into the action code. This is not required by Stellar but it’s advisable as a best practice. Official Actions would be hosted in the Stellar organisation on GitHub. Custom Actions could be created using Stellar. Tasks Tasks are specific to a project and implemented by the project developers. They are SAP ParsableCommand or AsyncParsableCommand which use actions to construct complex logic specific to the needs of the project. Executor Executor is a command line tool in the form of a package generated by Stellar. It’s the entry point to the user-defined tasks. Invoking tasks on the Executor is like invoking lanes in Fastlane. Both developers and CI would interface with the Executor (masked as Stellar) to perform all operations. E.g. stellar setup_environment --developer-mode stellar run_unit_tests module=OrderHistory stellar setup_demo_app module=OrderHistory stellar run_ui_tests module=OrderHistory device="iPhone 15 Pro" Stellar CLI Stellar CLI is a command line tool that takes care of the heavy lifting of dealing with the Executor and the Tasks. It allows the integration of Stellar in a project and it should expose the following main commands: init: initialise the project by creating an Exectutor package in the .stellar folder build: builds the Executor generating a binary that is shared with the team members and used by CI create-action: scaffolding to create a new action in the form of a package create-task: scaffolding to create a new task in the form of a package edit: opens the Executor package for editing, similar to tuist edit This design was presented to a restricted group of devs at Just Eat Takeaway and it didn't take long to get an agreement on it. It was clear that once Stellar was completed, we would have integrated it in the codebase. Wider design I believe that a combination of CLI tools can create complex, templateable and customizable stacks to support the creation and growth of iOS codebases. Based on the experience developed at JET working on a large modular project with lots of packages, helper tools and optimised CI pipelines, I wanted Stellar to be eventually part of a set of tools taking the name “Stellar Tools” that could enable the creation and the management of large codebases. Something like the following: Tuist: generates projects and workspaces programmatically PackageGenerator: generates packages using a DSL Stacker: creates a modular iOS project based on a DSL Stellar: automate tasks Workflows: generates GitHub Actions workflows that use Stellar From my old notes: Current state After a few months of development within this team (made of devs not working at Just Eat Takeaway), I realised things were not moving in the direction I desired and I decided it was not beneficial to continue the collaboration with the team. We stopped working on Stellar mainly due to different levels of commitment from each of us and focus on the wrong tasks signalling a lack of project management from my end. For example, a considerable amount of time and effort went into the implementation of a version management system (vastly inspired by the one used in Tuist) that was not part of the scope of the Stellar project. The experience left me bitter and demotivated, learning that sometimes projects are best started alone. We made the repo public on GitHub aware that it was far from being production-ready but in my opinion, it's no doubt a nice, inspiring, MVP. GitHub - StellarTools/Stellar Contribute to StellarTools/Stellar development by creating an account on GitHub. GitHubStellarTools GitHub - StellarTools/ActionDSL Contribute to StellarTools/ActionDSL development by creating an account on GitHub. GitHubStellarTools The intent was then to progress on my own or with my colleagues at JET. As things evolved in 2023, we embarked on big projects that continued to evolve the platform such as a massive migration to GitHub Actions. To this day, we still plan to remove Fastlane as our vision is to rely on external dependencies as little as possible but there is no plan to use Stellar as-is. I suspect that, for the infrastructure team at JET, things will evolve in a way that sees more CLI tools being implemented and more GitHub actions using them.

    CloudWatch dashboards and alarms on Mac instances

      CloudWatch is great for observing and monitoring resources and applications on AWS, on premises, and on other clouds.

      While it's trivial to have the agent running on Linux, it's a bit more involved for mac instances (which are commonly used as CI workers). The support was

      CloudWatch is great for observing and monitoring resources and applications on AWS, on premises, and on other clouds. While it's trivial to have the agent running on Linux, it's a bit more involved for mac instances (which are commonly used as CI workers). The support was announced in January 2021 for mac1.metal (Intel/x86_64) and I bumped into some challenges on mac2.metal (M1/ARM64) that the team at AWS helped me solve (see this issue on the GitHub repo). I couldn't find other articles nor precise documentation from AWS which is why I'm writing this article to walk you through a common CloudWatch setup. The given code samples are for the HashiCorp tools Packer and Terraform and focus on mac2.metal instances. I'll cover the following steps: install the CloudWatch agent on mac2.metal instances configure the CloudWatch agent create a CloudWatch dashboard setup CloudWatch alarms setup IAM permissions Install the CloudWatch agent The CloudWatch agent can be installed by downloading the pkg file listed on this page and running the installer. You probably want to bake the agent into your AMI, so here is the Packer code for mac2.metal (ARM): # Install wget via brew provisioner "shell" { inline = [ "source ~/.zshrc", "brew install wget" ] } # Install CloudWatch agent provisioner "shell" { inline = [ "source ~/.zshrc", "wget https://s3.amazonaws.com/amazoncloudwatch-agent/darwin/arm64/latest/amazon-cloudwatch-agent.pkg", "sudo installer -pkg ./amazon-cloudwatch-agent.pkg -target /" ] } For the agent to work, you'll need collectd (https://collectd.org/) to be installed on the machine, which is usually done via brew. Brew installs it at /opt/homebrew/sbin/. This is also a step you want to perform when creating your AMI. # Install collectd via brew provisioner "shell" { inline = [ "source ~/.zshrc", "brew install collectd" ] } Configure the CloudWatch agent In order to run, the agent needs a configuration which can be created using the wizard. This page defines the metric sets that are available. Running the wizard with the command below will allow you to generate a basic json configuration which you can modify later. sudo /opt/aws/amazon-cloudwatch-agent/bin/amazon-cloudwatch-agent-config-wizard The following is a working configuration for Mac instances so you can skip the process. { "agent": { "metrics_collection_interval": 60, "run_as_user": "root" }, "metrics": { "aggregation_dimensions": [ [ "InstanceId" ] ], "append_dimensions": { "AutoScalingGroupName": "${aws:AutoScalingGroupName}", "ImageId": "${aws:ImageId}", "InstanceId": "${aws:InstanceId}", "InstanceType": "${aws:InstanceType}" }, "metrics_collected": { "collectd": { "collectd_typesdb": [ "/opt/homebrew/opt/collectd/share/collectd/types.db" ], "metrics_aggregation_interval": 60 }, "cpu": { "measurement": [ "cpu_usage_idle", "cpu_usage_iowait", "cpu_usage_user", "cpu_usage_system" ], "metrics_collection_interval": 60, "resources": [ "*" ], "totalcpu": false }, "disk": { "measurement": [ "used_percent", "inodes_free" ], "metrics_collection_interval": 60, "resources": [ "*" ] }, "diskio": { "measurement": [ "io_time", "write_bytes", "read_bytes", "writes", "reads" ], "metrics_collection_interval": 60, "resources": [ "*" ] }, "mem": { "measurement": [ "mem_used_percent" ], "metrics_collection_interval": 60 }, "netstat": { "measurement": [ "tcp_established", "tcp_time_wait" ], "metrics_collection_interval": 60 }, "statsd": { "metrics_aggregation_interval": 60, "metrics_collection_interval": 10, "service_address": ":8125" }, "swap": { "measurement": [ "swap_used_percent" ], "metrics_collection_interval": 60 } } } } I have enhanced the output of the wizard with some reasonable metrics to collect. The configuration created by the wizard is almost working but it's lacking a fundamental config to make it work out-of-the-box: the collectd_typesdb value. Linux and Mac differ when it comes to the location of collectd and types.db, and the agent defaults to the Linux path even if it was built for Mac, causing the following error when trying to run the agent: ======== Error Log ======== 2023-07-23T04:57:28Z E! [telegraf] Error running agent: Error loading config file /opt/aws/amazon-cloudwatch-agent/etc/amazon-cloudwatch-agent.toml: error parsing socket_listener, open /usr/share/collectd/types.db: no such file or directory Moreover, the /usr/share/ folder is not writable unless you disable SIP (System Integrity Protection) which cannot be done on EC2 mac instances nor is something you want to do for security reasons. The final configuration is something you want to save in System Manager Parameter Store using the ssm_parameter resource in Terraform: resource "aws_ssm_parameter" "cw_agent_config_darwin" { name = "/cloudwatch-agent/config/darwin" description = "CloudWatch agent config for mac instances" type = "String" value = file("./cw-agent-config-darwin.json") } and use it when running the agent in a provisioning step: resource "null_resource" "run_cloudwatch_agent" { depends_on = [ aws_instance.mac_instance ] connection { type = "ssh" agent = false host = aws_instance.mac_instance.private_ip user = "ec2-user" private_key = tls_private_key.mac_instance.private_key_pem timeout = "30m" } # Run CloudWatch agent provisioner "remote-exec" { inline = [ "sudo /opt/aws/amazon-cloudwatch-agent/bin/amazon-cloudwatch-agent-ctl -a fetch-config -m ec2 -s -c ssm:${aws_ssm_parameter.cw_agent_config_darwin.name}" ] } } Create a CloudWatch dashboard Once the instances are deployed and running, they will send events to CloudWatch and we can create a dashboard to visualise them. You can create a dashboard manually in the console and once you are happy with it, you can just copy the source code, store it in a file and feed it to Terraform. Here is mine that could probably work for you too if you tag your instances with the Type set to macOS: { "widgets": [ { "height": 15, "width": 24, "y": 0, "x": 0, "type": "explorer", "properties": { "metrics": [ { "metricName": "cpu_usage_user", "resourceType": "AWS::EC2::Instance", "stat": "Average" }, { "metricName": "cpu_usage_system", "resourceType": "AWS::EC2::Instance", "stat": "Average" }, { "metricName": "disk_used_percent", "resourceType": "AWS::EC2::Instance", "stat": "Average" }, { "metricName": "diskio_read_bytes", "resourceType": "AWS::EC2::Instance", "stat": "Average" }, { "metricName": "diskio_write_bytes", "resourceType": "AWS::EC2::Instance", "stat": "Average" } ], "aggregateBy": { "key": "", "func": "" }, "labels": [ { "key": "Type", "value": "macOS" } ], "widgetOptions": { "legend": { "position": "bottom" }, "view": "timeSeries", "stacked": false, "rowsPerPage": 50, "widgetsPerRow": 1 }, "period": 60, "splitBy": "", "region": "eu-west-1" } } ] } You can then use the cloudwatch_dashboard resource in Terraform: resource "aws_cloudwatch_dashboard" "mac_instances" { dashboard_name = "mac-instances" dashboard_body = file("./cw-dashboard-mac-instances.json") } It will show something like this: Setup CloudWatch alarms Once the dashboard is up, you should set up alarms so that you are notified of any anomalies, rather than actively monitoring the dashboard for them. What works for me is having alarms triggered via email when the used disk space is going above a certain level (say 80%). We can use the cloudwatch_metric_alarm resource. resource "aws_cloudwatch_metric_alarm" "disk_usage" { alarm_name = "mac-${aws_instance.mac_instance.id}-disk-usage" comparison_operator = "GreaterThanThreshold" evaluation_periods = 30 metric_name = "disk_used_percent" namespace = "CWAgent" period = 120 statistic = "Average" threshold = 80 alarm_actions = [aws_sns_topic.disk_usage.arn] dimensions = { InstanceId = aws_instance.mac_instance.id } } We can then create an SNS topic and subscribe all interested parties to it. This will allow us to broadcast to all subscribers when the alarm is triggered. For this, we can use the sns_topic and sns_topic_subscription resources. resource "aws_sns_topic" "disk_usage" { name = "CW_Alarm_disk_usage_mac_${aws_instance.mac_instance.id}" } resource "aws_sns_topic_subscription" "disk_usage" { for_each = toset(var.alarm_subscriber_emails) topic_arn = aws_sns_topic.disk_usage.arn protocol = "email" endpoint = each.value } variable "alarm_subscriber_emails" { type = list(string) } If you are deploying your infrastructure via GitHub Actions, you can set your subscribers as a workflow input or as an environment variable. Here is how you should pass a list of strings via a variable in Terraform: name: Deploy Mac instance env: ALARM_SUBSCRIBERS: '["user1@example.com","user2@example.com"]' AMI: ... jobs: deploy: ... steps: - name: Terraform apply run: | terraform apply \ --var ami=${{ env.AMI }} \ --var alarm_subscriber_emails='${{ env.ALARM_SUBSCRIBERS }}' \ --auto-approve Setup IAM permissions The instance that performs the deployment requires permissions for CloudWatch, System Manager, and SNS. The following is a policy that is enough to perform both terraform apply and terraform destroy. Please consider restricting to specific resources. { "Version": "2012-10-17", "Statement": [ { "Sid": "CloudWatchDashboardsPermissions", "Effect": "Allow", "Action": [ "cloudwatch:DeleteDashboards", "cloudwatch:GetDashboard", "cloudwatch:ListDashboards", "cloudwatch:PutDashboard" ], "Resource": "*" }, { "Sid": "CloudWatchAlertsPermissions", "Effect": "Allow", "Action": [ "cloudwatch:DescribeAlarms", "cloudwatch:DescribeAlarmsForMetric", "cloudwatch:DescribeAlarmHistory", "cloudwatch:DeleteAlarms", "cloudwatch:DisableAlarmActions", "cloudwatch:EnableAlarmActions", "cloudwatch:ListTagsForResource", "cloudwatch:PutMetricAlarm", "cloudwatch:PutCompositeAlarm", "cloudwatch:SetAlarmState" ], "Resource": "*" }, { "Sid": "SystemsManagerPermissions", "Effect": "Allow", "Action": [ "ssm:GetParameter", "ssm:GetParameters", "ssm:ListTagsForResource", "ssm:DeleteParameter", "ssm:DescribeParameters", "ssm:PutParameter" ], "Resource": "*" }, { "Sid": "SNSPermissions", "Effect": "Allow", "Action": [ "sns:CreateTopic", "sns:DeleteTopic", "sns:GetTopicAttributes", "sns:GetSubscriptionAttributes", "sns:ListSubscriptions", "sns:ListSubscriptionsByTopic", "sns:ListTopics", "sns:SetSubscriptionAttributes", "sns:SetTopicAttributes", "sns:Subscribe", "sns:Unsubscribe" ], "Resource": "*" } ] } On the other hand, to send logs to CloudWatch, the Mac instances require permissions given by the CloudWatchAgentServerPolicy: resource "aws_iam_role_policy_attachment" "mac_instance_iam_role_cw_policy_attachment" { role = aws_iam_role.mac_instance_iam_role.name policy_arn = "arn:aws:iam::aws:policy/CloudWatchAgentServerPolicy" } Conclusion You have now defined your CloudWatch dashboard and alarms using "Infrastructure as Code" via Packer and Terraform. I've covered the common use case of instances running out of space on disk which is useful to catch before CI starts becoming unresponsive slowing your team down.

      Easy connection to AWS Mac instances with EC2macConnector

        Overview

        Amazon Web Services (AWS) provides EC2 Mac instances commonly used as CI workers. Configuring them can be either a manual or an automated process, depending on the DevOps and Platform Engineering experience in your company. No matter what process you adopt, it is sometimes useful to log into the

        Overview Amazon Web Services (AWS) provides EC2 Mac instances commonly used as CI workers. Configuring them can be either a manual or an automated process, depending on the DevOps and Platform Engineering experience in your company. No matter what process you adopt, it is sometimes useful to log into the instances to investigate problems. EC2macConnector is a CLI tool written in Swift that simplifies the process of connecting over SSH and VNC for DevOps engineers, removing the need of updating private keys and maintaining the list of IPs that change across deployment cycles. Connecting to EC2 Mac instances without EC2macConnector AWS documentation describes the steps needed to allow connecting via VNC: Start the Apple Remote Desktop agent and enable remote desktop access on the instance Set the password for the ec2-user user on the instance to allow connecting over VNC Start an SSH session Connect over VNC Assuming steps 1 and 2 and done, steps 3 and 4 are usually manual and repetitive: the private keys and IPs usually change across deployments which could happen frequently, even daily. Here is how to start an SSH session in the terminal binding a port locally: ssh ec2-user@<instance_IP> \ -L <local_port>:localhost:5900 \ -i <path_to_privae_key> \ To connect over VNC you can type the following in Finder → Go → Connect to Server (⌘ + K) and click Connect: vnc://ec2-user@localhost:<local_port> or you could create a .vncloc file with the following content and simply open it: <?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "<http://www.apple.com/DTDs/PropertyList-1.0.dtd>"> <plist version="1.0"> <dict> <key>URL</key> <string>vnc://ec2-user@localhost:<local_port></string> </dict> </plist> If you are a system administrator, you might consider EC2 Instance Connect, but sadly, in my experience, it's not a working option for EC2 Mac instances even though I couldn't find evidence confirming or denying this statement. Administrators could also consider using Apple Remote Desktop which comes with a price tag of $/£79.99. Connecting to EC2 Mac instances with EC2macConnector EC2macConnector is a simple and free tool that works in 2 steps: the configure command fetches the private keys and the IP addresses of the running EC2 Mac instances in a given region, and creates files using the said information to connect over SSH and VNC: ec2macConnector configure \ --region <aws_region> \ --secrets-prefix <mac_metal_private_keys_prefix> Read below or the README for more information on the secrets prefix value. the connect command connects to the instances via SSH or VNC. ec2macConnector connect --region <aws_region> <fleet_index> ec2macConnector connect --region <aws_region> <fleet_index> --vnc 💡 Connecting over VNC requires an SSH session to be established first. As with any tool written using ArgumentParser, use the --help flag to get more information. Requirements There are some requirements to respect for the tool to work: Permissions EC2macConnector requires AWS credentials either set as environment variables (AWS_ACCESS_KEY_ID and AWS_SECRET_ACCESS_KEY) or configured in ~/.aws/credentials via the AWS CLI. Environment variables take precedence. The user must be granted the following permissions: ec2:DescribeInstances secretsmanager:ListSecrets secretsmanager:GetSecretValue EC2 instances The EC2 Mac instances must have the EC2macConnector:FleetIndex tag set to the index of the instance in the fleet. Indexes should start at 1. Instances that don't have the said tag will be ignored. Secrets and key pairs formats EC2macConnector assumes that the private key for each instance key pair is stored in SecretsManagers. The name of the key pair could and should be different from the secret ID. For example, the instance key pair should include an incremental number also part of the corresponding secret ID. Consider that the number of Mac instances in an AWS account is limited and it's convenient to refer to them using an index starting at 1. It's good practice for the secret ID to also include a nonce as secrets with the same name cannot be recreated before the deletion period has elapsed, allowing frequent provisioning-decommissioning cycles. For the above reasons, EC2macConnector assumes the following formats are used: instance key pairs: <keypair_prefix>_<index_of_instance_in_fleet> e.g. mac_instance_key_pair_5 secret IDs: <secrets_prefix>_<index_of_instance_in_fleet>_<nonce> e.g. private_key_mac_metal_5_dx9Wna73B EC2macConnector Under the hood The configure command: downloads the private keys in the ~/.ssh folder creates scripts to connect over SSH in ~/.ec2macConnector/<region>/scripts creates vncloc files to connect over VNC in ~/.ec2macConnector/<region>/vnclocs ➜ .ec2macConnector tree ~/.ssh /Users/alberto/.ssh ├── mac_metal_1_i-08e4ffd8e9xxxxxxx ├── mac_metal_2_i-07bfff1f52xxxxxxx ├── mac_metal_3_i-020d680610xxxxxxx ├── mac_metal_4_i-08516ac980xxxxxxx ├── mac_metal_5_i-032bedaabexxxxxxx ├── config ├── known_hosts └── ... The connect command: runs the scripts (opens new shells in Terminal and connects to the instances over SSH) opens the vncloc files ➜ .ec2macConnector tree ~/.ec2macConnector /Users/alberto/.ec2macConnector └── us-east-1 ├── scripts │   ├── connect_1.sh │   ├── connect_2.sh │   ├── connect_3.sh │   ├── connect_4.sh │   └── connect_5.sh └── vnclocs ├── connect_1.vncloc ├── connect_2.vncloc ├── connect_3.vncloc ├── connect_4.vncloc └── connect_5.vncloc

        Toggles: the easiest feature flagging in Swift

          I previously wrote about JustTweak here. It's the feature flagging mechanism we've been using at Just Eat Takeaway.com to power the iOS consumer apps since 2017. It's proved to be very stable and powerful and it has evolved over time. Friends have heard

          I previously wrote about JustTweak here. It's the feature flagging mechanism we've been using at Just Eat Takeaway.com to power the iOS consumer apps since 2017. It's proved to be very stable and powerful and it has evolved over time. Friends have heard me promoting it vehemently and some have integrated it with success and appreciation. I don't think I've promoted it in the community enough (it definitely deserved more) but marketing has never been my thing. Anyway, JustTweak grew old and some changes were debatable and not to my taste. I have then decided to use the knowledge of years of working on the feature flagging matter to give this project a new life by rewriting it from scratch as a personal project. And here it is: Toggles. I never tweeted about this side project of mine 😜 It's like JustTweak (feature flagging), but sensibly better. https://t.co/bdGWuUyQEU #Swift #iOS #macOS — Alberto De Bortoli (@albertodebo) March 23, 2023 Think of JustTweak, but better. A lot better. Frankly, I couldn't have written it better. Here are the main highlights: brand new code, obsessively optimized and kept as short and simple as possible extreme performances fully tested fully documented performant UI debug view in SwiftUI standard providers provided demo app provided ability to listen for value changes (using Combine) simpler APIs ToggleGen CLI, to allow code generation ToggleCipher CLI, to allow encoding/decoding of secrets JustTweakMigrator CLI, to allow a smooth transition from JustTweak Read all about it on the repo's README and on the DocC page. It's on Swift Package Index too. Toggles – Swift Package Index Toggles by TogglesPlatform on the Swift Package Index – Toggles is an elegant and powerful solution to feature flagging for Apple platforms. Learn more There are plans (or at least the desire!) to write a backend with Andrea Scuderi. That'd be really nice! @albertodebo This wasn't planned! It looks like we need to build the backend for #Toggles with #Breeze! pic.twitter.com/OxNovRl70L — andreascuderi (@andreascuderi13) March 26, 2023

          The Continuous Integration system used by the mobile teams

          • iOS
          • Continuous Integration
          • Jenkins
          • DevOps

          In this article, we’ll discuss the way our mobile teams have evolved the Continuous Integration (CI) stack over the recent years.

          Originally published on the Just Eat Takeaway Engineering Blog. Overview In this article, we’ll discuss the way our mobile teams have evolved the Continuous Integration (CI) stack over the recent years. We don’t have DevOps engineers in our team and, until recently, we had adopted a singular approach in which CI belongs to the whole team and everyone should be able to maintain it. This has proven to be difficult and extremely time-consuming. The Just Eat side of our newly merged entity has a dedicated team providing continuous integration and deployment tools to their teams but they are heavily backend-centric and there has been little interest in implementing solutions tailored for mobile teams. As is often the case in tech companies, there is a missing link between mobile and DevOps teams. The iOS team is the author and first consumer of the solution described but, as you can see, we have ported the same stack to Android as well. We will mainly focus on the iOS implementation in this article, with references to Android as appropriate. 2016–2020 Historically speaking, the iOS UK app was running on Bitrise because it was decided not to invest time in implementing a CI solution, while the Bristol team was using a Jenkins version installed by a different team. This required manual configuration with custom scripts and it had custom in-house hardware. These are two quite different approaches indeed and, at this stage, things were not great but somehow good enough. It’s fair to say we were still young on the DevOps front. When we merged the teams, it was clear that we wanted to unify the CI solution and the obvious choice for a company of our size was to not use a third-party service, bringing us to invest more and more in Jenkins. Only one team member had good knowledge of Jenkins but the rest of the team showed little interest in learning how to configure and maintain it, causing the stack to eventually become a dumping ground of poorly configured jobs. It was during this time that we introduced Fastlane (making the common tasks portable), migrated the UK app from Bitrise to Jenkins, started running the UI tests on Pull Requests, and other small yet sensible improvements. 2020–2021 Starting in mid-2020 the iOS team has significantly revamped its CI stack and given it new life. The main goals we wanted to achieve (and did by early 2021) were: Revisit the pipelines Clear Jenkins configuration and deployment strategy Make use of AWS Mac instances Reduce the pool size of our mac hardware Share our knowledge across teams better Since the start of the pandemic, we have implemented the pipelines in code (bidding farewell to custom bash scripts), we moved to a monorepo which was a massive step ahead and began using SonarQube even more aggressively. We added Slack reporting and PR Assigner, an internal tool implemented by Andrea Antonioni. We also automated the common release tasks such as cutting and completing a release and uploading the dSYMS to Firebase. We surely invested a lot in optimizing various aspects such as running the UI tests in parallel, making use of shallow repo cloning, We also moved to not checking in the pods within the repo. This, eventually, allowed us to reduce the number of agents for easier infrastructure maintenance. Automating the infrastructure deployment of Jenkins was a fundamental shift compared to the previous setup and we have introduced AWS Mac instances replacing part of the fleet of our in-house hardware. CI system setup Let’s take a look at our stack. Before we start, we’d like to thank Isham Araia for having provided a proof of concept for the configuration and deployment of Jenkins. He talked about it at https://ish-ar.io/jenkins-at-scale/ and it represented a fundamental starting point, saving us several days of researching. Triggering flow Starting from the left, we have our repositories (plural, as some shared dependencies don’t live in the monorepo). The repositories contain the pipelines in the form of Jenkinsfiles and they call into Fastlane lanes. Pretty much every action is a lane, from running the tests to archiving for the App Store to creating the release branches. Changes are raised through pull requests that trigger Jenkins. There are other ways to trigger Jenkins: by user interaction (for things such as completing a release or archiving and uploading the app to App Store Connect) and cron triggers (for things such as building the nightly build, running the tests on the develop branch every 12 hours, or uploading the PACT contract to the broker). Once Jenkins has received the information, it will then schedule the jobs to one of the agents in our pool, which is now made up of 5 agents, 2 in the cloud and 3 in-house mac pros. Reporting flow Now that we’ve talked about the first part of the flow, let’s talk about the flow of information coming back at us. Every PR triggers PR Assigner, a tool that works out a list of reviewers to assign to pull requests and notifies engineers via dedicated Slack channels. The pipelines post on Slack, providing info about all the jobs that are being executed so we can read the history without having to log into Jenkins. We have in place the standard notification flow from Jenkins to GitHub to set the status checks and Jenkins also notifies SonarQube to verify that any change meets the quality standards (namely code coverage percentage and coding rules). We also have a smart lambda named SonarQubeStatusProcessor that reports to GitHub, written by Alan Nichols. This is due to a current limitation of SonarQube, which only allows reporting the status of one SQ project to one GitHub repo. Since we have a monorepo structure we had to come up with this neat customization to report the SQ status for all the modules that have changed as part of the PR. Configuration Let’s see what the new interesting parts of Jenkins are. Other than Jenkins itself and several plugins, it’s important to point out JCasC and Job DSL. JCasC stands for Jenkins Configuration as Code, and it allows you to configure Jenkins via a yaml file. The point here is that nobody should ever touch the Jenkins settings directly from the configuration page, in the same way, one ideally shouldn’t apply configuration changes manually in any dashboard. The CasC file is where we define the Slack integration, the user roles, SSO configuration, the number of agents and so on. We could also define the jobs in CasC but we go a step further than that. We use the Job DSL plugin that allows you to configure the jobs in groovy and in much more detail. One job we configure in the CasC file though is the seed job. This is a simple freestyle job that will go pick the jobs defined with Job DSL and create them in Jenkins. Deployment Let’s now discuss how we can get a configured Jenkins instance on EC2. In other words, how do we deploy Jenkins? We use a combination of tools that are bread and butter for DevOps people. The commands on the left spawn a Docker container that calls into the tools on the right. We start with Packer which allows us to create the AMI (Amazon Machine Image) together with Ansible, allowing us to configure an environment easily (much more easily than Chef or Puppet). Running the create-image command the script will: 1. Create a temporary EC2 instance 2. Connect to the instance and execute an ansible playbook Our playbook encompasses a number of steps, here’s a summary: install the Jenkins version for the given Linux distribution install Nginx copy the SSL cert over configure nginx w/ SSL termination and reverse proxy install the plugins for Jenkins Once the playbook is executed, Packer will export an AMI in EC2 with all of this in it and destroy the instance that was used. With the AMI ready, we can now proceed to deploy our Jenkins. For the actual deployment, we use Terraform which allows us to define our infrastructure in code. The deploy command runs Terraform under the hood to set up the infrastructure, here’s a summary of the task: create an IAM Role + IAM Policy configure security groups create the VPC and subnet to use with a specific CIDER block and the subnet create any private key pair to connect over SSH deploy the instance using a static private IP (it has to be static otherwise the A record in Route53 would break) copy the JCasC configuration file over so that when Jenkins starts it picks that up to configure itself The destroy command runs a “terraform destroy” and destroys everything that was created with the deploy command. Deploy and destroy balance each other out. Now that we have Jenkins up and running, we need to give it some credentials so our pipelines are able to work properly. A neat way of doing this is by having the secrets (SSH keys, Firebase tokens, App Store Connect API Key and so forth) in AWS Secrets Manager which is based on KMS and use a Jenkins plugin to allow Jenkins to access them. It’s important to note that developers don’t have to install Packer, Ansible, Terraform or even the AWS CLI locally because the commands run a Docker container that does the real work with all the tools installed. As a result, the only thing one should have installed is really Docker. CI agents Enough said about Jenkins, it’s time to talk about the agents.As you probably already know, in order to run tests, compile and archive iOS apps we need Xcode, which is only available on macOS, so Linux or Windows instances are not going to cut it. We experimented with the recently introduced AWS Mac instances and they are great, ready out-of-the-box with minimal configuration on our end. What we were hoping to get to with this recent work was the ability to leverage the Jenkins Cloud agents. That would have been awesome because it would have allowed us to: let Jenkins manage the agent instances scale the agent pool according to the load on CI Sadly we couldn't go that far. Limitations are: the bootstrapping of a mac1.metal takes around 15 minutes reusing the dedicated host after having stopped an instance can take up to 3 hours — during that time we just pay for a host that is not usable When you stop or terminate a Mac instance, Amazon EC2 performs a scrubbing workflow on the underlying Dedicated Host to erase the internal SSD, to clear the persistent NVRAM variables, and if needed, to update the bridgeOS software on the underlying Mac mini. This ensures that Mac instances provide the same security and data privacy as other EC2 Nitro instances. It also enables you to run the latest macOS AMIs without manually updating the bridgeOS software. During the scrubbing workflow, the Dedicated Host temporarily enters the pending state. If the bridgeOS software does not need to be updated, the scrubbing workflow takes up to 50 minutes to complete. If the bridgeOS software needs to be updated, the scrubbing workflow can take up to 3 hours to complete. Source: https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/ec2-mac-instances.html In other words: scaling mac instances is not an option and leaving the instances up 24/7 seems to be the easiest option. This is especially valid if your team is distributed and jobs could potentially run over the weekend as well, saving you the hassle of implementing downscaling ahead of the weekend. There are some pricing and instance allocation considerations to make. Note that On-Demand Mac1 Dedicated Hosts have a minimum host allocation and billing duration of 24 hours. “You can purchase Savings Plans to lower your spend on Dedicated Hosts. Savings Plans is a flexible pricing model that provides savings of up to 72% on your AWS compute usage. This pricing model offers lower prices on Amazon EC2 instances usage, regardless of instance family, size, OS, tenancy or AWS Region.” Source: https://aws.amazon.com/ec2/dedicated-hosts/pricing/ The On-Demand rate is $1.207 per hour. I’d like to stress that no CI solution comes for free. I’ve often heard developers indicating that Travis and similar products are cheaper. The truth is that the comparison is not even remotely reasonable: virtual boxes are incredibly slow compared to native Apple hardware and take ridiculous bootstrapping times. Even the smallest projects suffer terribly. One might ask if it’s at least possible to use the same configuration process we used for the Jenkins instance (with Packer and Ansible) but sadly we hit additional limitations: Apple requires 2FA for downloading Xcode via xcode-version Apple requires 2FA for signing into Xcode The above pretty much causes the configuration flow to fall apart making it impossible to configure an instance via Ansible. Cloud agents for Android It was a different story for Android, in which we could easily configure the agent instance with Ansible and therefore leverage the Cloud configuration to allow automatic agent provisioning. This configuration is defined via CasC as everything else. To better control EC2 usage and costs, a few settings come in handy: minimum number of instances (up at all times) minimum number of spare instances (created to accommodate future jobs) instance cap: the maximum number of instances that can be provisioned at the same time idle termination time: how long agents should be kept alive after they have completed the job All of the above allow for proper scaling and a lot less maintenance compared to the iOS setup. A simple setup with 0 instances up at all times allows saving costs overnight and given that in our case the bootstrapping takes only 2 minutes, we can rely on the idle time setting. Conclusions Setting up an in-house CI is never a straightforward process and it requires several weeks of dedicated work. After years of waiting, Apple has announced Xcode Cloud which we believe will drastically change the landscape of continuous integration on iOS. The solution will most likely cause havoc for companies such as Bitrise and CircleCI and it’s reasonable to assume the pricing will be competitive compared to AWS, maybe running on custom hardware that only Apple is able to produce. A shift this big will take time to occur, so we foresee our solution to stay in use for quite some time. We hope to have inspired you on how a possible setup for mobile teams could be and informed you on what are the pros & cons of using EC2 mac instances.

          iOS Monorepo & CI Pipelines

          • iOS
          • Monorepo
          • Continuous Integration
          • Jenkins
          • Cocoapods

          We have presented our modular iOS architecture in a previous article and I gave a talk at Swift Heroes 2020 about it. In this article, we’ll analyse the challenges we faced to have the modular architecture integrated with our CI pipelines and the reasoning behind migrating to a monorepo.

          Originally published on the Just Eat Takeaway Engineering Blog. We have presented our modular iOS architecture in a previous article and I gave a talk at Swift Heroes 2020 about it. In this article, we’ll analyse the challenges we faced to have the modular architecture integrated with our CI pipelines and the reasoning behind migrating to a monorepo. The Problem Having several modules in separate repositories brings forward 2 main problems: Each module is versioned independently from the consuming app Each change involves at least 2 pull requests: 1 for the module and 1 for the integration in the app While the above was acceptable in a world where we had 2 different codebases, it soon became unnecessarily convoluted after we migrated to a new, global codebase. New module versions are implemented with the ultimate goal of being adopted by the only global codebase in use, making us realise we could simplify the change process. The monorepo approach has been discussed at length by the community for a few years now. Many talking points have come out of these conversations, even leading to an interesting story as told by Uber. In short, it entails putting all the code owned by the team in a single repository, precisely solving the 2 problems stated above. Monorepo structure The main advantage of a monorepo is a streamlined PR process that doesn’t require us to raise multiple PRs, de facto reducing the number of pull requests to one. It also simplifies the versioning, allowing module and app code (ultimately shipped together) to be aligned using the same versioning. The first step towards a monorepo was to move the content of the repositories of the modules to the main app repo (we’ll call it “monorepo” from now on). Since we rely on CocoaPods, the modules would be consumed as development pods. Here’s a brief summary of the steps used to migrate a module to the monorepo: Inform the relevant teams about the upcoming migration Make sure there are no open PRs in the module repo Make the repository read-only and archive it Copy the module to the Modules folder of the monorepo (it’s possible to merge 2 repositories to keep the history but we felt we wanted to keep the process simple, the old history is still available in the old repo anyway) Delete the module .git folder (or it would cause a git submodule) Remove Gemfile and Gemfile.lock fastlane folder, .gitignore file, sonar-project.properties, .swiftlint.yml so to use those in the monorepo Update the monorepo’s CODEOWNERS file with the module codeowners Remove the .github folder Modify the app Podfile to point to the module as a dev pod and install it Make sure all the modules’ demo apps in the monorepo refer to the new module as a dev pod (if they depend on it at all). The same applies to the module under migration. Delete the CI jobs related to the module Leave the podspecs in the private Specs repo (might be needed to build old versions of the app) The above assumes that CI is configured in a way that preserves the same integration steps upon a module change. We’ll discuss them later in this article. Not all the modules could be migrated to the monorepo, due to the fact the second-level dependencies need to live in separate repositories in order to be referenced in the podspec of a development pod. If not done correctly, CocoaPods will not be able to install them. We considered moving these dependencies to the monorepo whilst maintaining separate versioning, however, the main problem with this approach is that the version tags might conflict with the ones of the app. Even though CocoaPods supports tags that don’t respect semantic versioning (for example prepending the tag with the name of the module), violating it just didn’t feel right. EDIT: we’ve learned that it’s possible to move such dependencies to the monorepo. This is done not by defining :path=> in the podspecs but instead by doing so in the Podfile of the main app, which is all Cocoapods needs to work out the location of the dependency on disk. Swift Package Manager considerations We investigated the possibility of migrating from CocoaPods to Apple’s Swift Package Manager. Unfortunately, when it comes to handling the equivalent of development pods, Swift Package Manager really falls down for us. It turns out that Swift Package Manager only supports one package per repo, which is frustrating because the process of working with editable packages is surprisingly powerful and transparent. Version pinning rules While development pods don’t need to be versioned, other modules still need to. This is either because of their open-source nature or because they are second-level dependencies (referenced in other modules’ podspecs). Here’s a revised overview of the current modular architecture in 2021. We categorised our pods to better clarify what rules should apply when it comes to version pinning both in the Podfiles and in the podspecs. Open-Source pods Our open-source repositories on github.com/justeat are only used by the app. Examples: JustTweak, AutomationTools, Shock Pinning in other modules’ podspec: NOT APPLICABLE open-source pods don’t appear in any podspec, those that do are called ‘open-source shared’ Pinning in other modules’ Podfile (demo apps): PIN (e.g. AutomationTools in Orders demo app’s Podfile) Pinning in main app’s Podfile: PIN (e.g. AutomationTools) Open-Source shared pods The Just Eat pods we put open-source on github.com/justeat and are used by modules and apps. Examples: JustTrack, JustLog, ScrollingStackViewController, ErrorUtilities Pinning in other modules’ podspec: PIN w/ optimistic operator (e.g. JustTrack in Orders) Pinning in other modules’ Podfile (demo apps): PIN (e.g. JustTrack in Orders demo app’s Podfile) Pinning in main app’s Podfile: DON’T LIST latest compatible version is picked by CocoaPods (e.g. JustTrack). LIST & PIN if the pod is explicitly used in the app too, so we don’t magically inherit it. Internal Domain pods Domain modules (yellow). Examples: Orders, SERP, etc. Pinning in other modules’ podspec: NOT APPLICABLE domain pods don’t appear in other pods’ podspecs (domain modules don’t depend on other domain modules) Pinning in other modules’ Podfile (demo apps): PIN only if the pod is used in the app code, rarely the case (e.g. Account in Orders demo app’s Podfile) Pinning in main app’s Podfile: PIN (e.g. Orders) Internal Core pods Core modules (blue) minus those open-source. Examples: APIClient, AssetProvider Pinning in other modules’ podspec: NOT APPLICABLE core pods don’t appear in other pods’ podspecs (core modules are only used in the app(s)) Pinning in other modules’ Podfile (demo apps): PIN only if pod is used in the app code (e.g. APIClient in Orders demo app’s Podfile) Pinning in main app’s Podfile: PIN (e.g. NavigationEngine) Internal shared pods Shared modules (green) minus those open-source. Examples: JustUI, JustAnalytics Pinning in other modules’ podspec: DON’T PIN (e.g. JustUI in Orders podspec) Pinning in other modules’ Podfile (demo apps): PIN (e.g. JustUI in Orders demo app’s Podfile) Pinning in main app’s Podfile: PIN (e.g. JustUI) External shared pods Any non-Just Eat pod used by any internal or open-source pod. Examples: Usabilla, SDWebImage Pinning in other modules’ podspec: PIN (e.g. Usabilla in Orders) Pinning in other modules’ Podfile (demo apps): DON’T LIST because the version is forced by the podspec. LIST & PIN if the pod is explicitly used in the app too, so we don’t magically inherit it. Pinning is irrelevant but good practice. Pinning in main app’s Podfile: DON’T LIST because the version is forced by the podspec(s). LIST & PIN if the pod is explicitly used in the app too, so we don’t magically inherit it. Pinning is irrelevant but good practice. External pods Any non-Just Eat pod used by the app only. Examples: Instabug, GoogleAnalytics Pinning in other modules’ podspec: NOT APPLICABLE external pods don’t appear in any podspec, those that do are called ‘external shared’ Pinning in other modules’ Podfile (demo apps): PIN only if the pod is used in the app code, rarely the case (e.g. Promis) Pinning in main app’s Podfile: PIN (e.g. Adjust) Pinning is a good solution because it guarantees that we always build the same software regardless of new released versions of dependencies. It’s also true that pinning every dependency all the time makes the dependency graph hard to keep updated. This is why we decided to allow some flexibility in some cases. Following is some more reasoning. Open-source For “open-source shared” pods, we are optimistic enough (pun intended) to tolerate the usage of the optimistic operator ~> in podspecs of other pods (i.e Orders using JustTrack) so that when a new patch version is released, the consuming pod gets it for free upon running pod update. We have control over our code and, by respecting semantic versioning, we guarantee the consuming pod to always build. In case of new minor or major versions, we would have to update the podspecs of the consuming pods, which is appropriate. Also, we do need to list any “open-source shared” pod in the main app’s Podfile only if directly used by the app code. External We don’t have control over the “external” and “external shared” pods, therefore we always pin the version in the appropriate place. New patch versions might not respect semantic versioning for real and we don’t want to pull in new code unintentionally. As a rule of thumb, we prefer injecting external pods instead of creating a dependency in the podspec. Internal Internal shared pods could change frequently (not as much as domain modules). For this reason, we’ve decided to relax a constraint we had and not to pin the version in the podspec. This might cause the consuming pod to break when a new version of an “internal shared” pod is released and we run pod update. This is a compromise we can tolerate. The alternative would be to pin the version causing too much work to update the podspec of the domain modules. Continuous Integration changes With modules in separate repositories, the CI was quite simply replicating the same steps for each module: install pods run unit tests run UI tests generated code coverage submit code coverage to SonarQube Moving the modules to the monorepo meant creating smart CI pipelines that would run the same steps upon modules’ changes. If a pull request is to change only app code, there is no need to run any step for the modules, just the usual steps for the app: If instead, a pull request applies changes to one or more modules, we want the pipeline to first run the steps for the modules, and then the steps for the app: Even if there are no changes in the app code, module changes could likely impact the app behaviour, so it’s important to always run the app tests. We have achieved the above setup through constructing our Jenkins pipelines dynamically. The solution should scale when new modules are added to the monorepo and for this reason, it’s important that all modules: respect the same project setup (generated by CocoaPods w/ the pod lib create command) use the same naming conventions for the test schemes (UnitTests/ContractTests/UITests) make use of Apple Test Plans are in the same location ( ./Modules/ folder). Following is an excerpt of the code that constructs the modules’ stages from the Jenkinsfile used for pull request jobs. scripts = load "./Jenkins/scripts/scripts.groovy" def modifiedModules = scripts.modifiedModulesFromReferenceBranch(env.CHANGE_TARGET) def modulesThatNeedUpdating = scripts.modulesThatNeedUpdating(env.CHANGE_TARGET) def modulesToRun = (modulesThatNeedUpdating + modifiedModules).unique() sh "echo \"List of modules modified on this branch: ${modifiedModules}\"" sh "echo \"List of modules that need updating: ${modulesThatNeedUpdating}\"" sh "echo \"Pipeline will run the following modules: ${modulesToRun}\"" for (int i = 0; i < modulesToRun.size(); ++i) { def moduleName = modulesToRun[i] stage('Run pod install') { sh "bundle exec fastlane pod_install module:${moduleName}" } def schemes = scripts.testSchemesForModule(moduleName) schemes.each { scheme -> switch (scheme) { case "UnitTests": stage("${moduleName} Unit Tests") { sh "bundle exec fastlane module_unittests \ module_name:${moduleName} \ device:'${env.IPHONE_DEVICE}'" } stage("Generate ${moduleName} code coverage") { sh "bundle exec fastlane generate_sonarqube_coverage_xml" } stage("Submit ${moduleName} code coverage to SonarQube") { sh "bundle exec fastlane sonar_scanner_pull_request \ component_type:'module' \ source_branch:${env.BRANCH_NAME} \ target_branch:${env.CHANGE_TARGET} \ pull_id:${env.CHANGE_ID} \ project_key:'ios-${moduleName}' \ project_name:'iOS ${moduleName}' \ sources_path:'./Modules/${moduleName}/${moduleName}'" } break; case "ContractTests": stage('Install pact mock service') { sh "bundle exec fastlane install_pact_mock_service" } stage("${moduleName} Contract Tests") { sh "bundle exec fastlane module_contracttests \ module_name:${moduleName} \ device:'${env.IPHONE_DEVICE}'" } break; case "UITests": stage("${moduleName} UI Tests") { sh "bundle exec fastlane module_uitests \ module_name:${moduleName} \ number_of_simulators:${env.NUMBER_OF_SIMULATORS} \ device:'${env.IPHONE_DEVICE}'" } break; default: break; } } } and here are the helper functions to make it all work: def modifiedModulesFromReferenceBranch(String referenceBranch) { def script = "git diff --name-only remotes/origin/${referenceBranch}" def filesChanged = sh script: script, returnStdout: true Set modulesChanged = [] filesChanged.tokenize("\n").each { def components = it.split('/') if (components.size() > 1 && components[0] == 'Modules') { def module = components[1] modulesChanged.add(module) } } return modulesChanged } def modulesThatNeedUpdating(String referenceBranch) { def modifiedModules = modifiedModulesFromReferenceBranch(referenceBranch) def allModules = allMonorepoModules() def modulesThatNeedUpdating = [] for (module in allModules) { def podfileLockPath = "Modules/${module}/Example/Podfile.lock" def dependencies = podfileDependencies(podfileLockPath) def dependenciesIntersection = dependencies.intersect(modifiedModules) as TreeSet Boolean moduleNeedsUpdating = (dependenciesIntersection.size() > 0) if (moduleNeedsUpdating == true && modifiedModules.contains(module) == false) { modulesThatNeedUpdating.add(module) } } return modulesThatNeedUpdating } def podfileDependencies(String podfileLockPath) { def dependencies = [] def fileContent = readFile(file: podfileLockPath) fileContent.tokenize("\n").each { line -> def lineComponents = line.split('\\(') if (lineComponents.length > 1) { def dependencyLineSubComponents = lineComponents[0].split('-') if (dependencyLineSubComponents.length > 1) { def moduleName = dependencyLineSubComponents[1].trim() dependencies.add(moduleName) } } } return dependencies } def allMonorepoModules() { def modulesList = sh script: "ls Modules", returnStdout: true return modulesList.tokenize("\n").collect { it.trim() } } def testSchemesForModule(String moduleName) { def script = "xcodebuild -project ./Modules/${moduleName}/Example/${moduleName}.xcodeproj -list" def projectEntitites = sh script: script, returnStdout: true def schemesPart = projectEntitites.split('Schemes:')[1] def schemesPartLines = schemesPart.split(/\n/) def trimmedLined = schemesPartLines.collect { it.trim() } def filteredLines = trimmedLined.findAll { !it.allWhitespace } def allowedSchemes = ['UnitTests', 'ContractTests', 'UITests'] def testSchemes = filteredLines.findAll { allowedSchemes.contains(it) } return testSchemes } You might have noticed the modulesThatNeedUpdating method in the code above. Each module comes with a demo app using the dependencies listed in its Podfile and it’s possible that other monorepo modules are listed there as development pods. This not only means that we have to run the steps for the main app, but also the steps for every module consuming modules that show changes. For example, the Orders demo app uses APIClient, meaning that pull requests with changes in APIClient will generate pipelines including the Orders steps. Pipeline parallelization Something we initially thought was sensible to consider is the parallelisation of the pipelines across different nodes. We use parallelisation for the release pipelines and learned that, while it seems to be a fundamental requirement at first, it soon became apparent not to be so desirable nor truly fundamental for the pull requests pipeline. We’ll discuss our CI setup in a separate article, but suffice to say that we have aggressively optimized it and managed to reduce the agent pool from 10 to 5, still maintaining a good level of service. Parallelisation sensibly complicates the Jenkinsfiles and their maintainability, spreads the cost of checking out the repository across nodes and makes the logs harder to read. The main benefit would come from running the app UI tests on different nodes. In the WWDC session 413, Apple recommends generating the .xctestrun file using the build-for-testing option in xcodebuild and distribute it across the other nodes. Since our app is quite large, such file is also large and transferring it has its costs, both in time and bandwidth usage. All things considered, we decided to keep the majority of our pipelines serial. EDIT: In 2022 we have parallelised our PR pipeline in 4 branches: Validation steps (linting, Fastlane lanes tests, etc.) App unit tests App UI tests (short enough that there's no need to share .xctestrun across nodes) Modified modules unit tests Modified modules UI tests Conclusions We have used the setup described in this article since mid-2020 and we are very satisfied with it. We discussed the pipeline used for the pull requests which is the most relevant one when it comes to embracing a monorepo structure. We have a few more pipelines for various use cases, such as verifying changes in release branches, keeping the code coverage metrics up-to-date with jobs running of triggers, archiving the app for internal usage and for App Store. We hope to have given you some useful insights on how to structure a monorepo and its CI pipelines, especially if you have a structure similar to ours.

          Swift Heroes Digital 2020

          • Just Eat
          • Swift Heroes
          • Modular Architecture

          Hey there!

          I had the pleasure to talk at Swift Heroes Digital on October 1, 2020.

          The talk "Scalable Modular iOS Architecture" is about the unfolding of a multi-year iOS vision at Just Eat, restructuring the whole app from the ground up to make it modular and global

          Hey there! I had the pleasure to talk at Swift Heroes Digital on October 1, 2020. The talk "Scalable Modular iOS Architecture" is about the unfolding of a multi-year iOS vision at Just Eat, restructuring the whole app from the ground up to make it modular and global across various markets. I also covered some (I think) interesting bits about the history of the iOS team and the tech side of the company. Here's the recording, hope you like it 😊

          The algorithm powering iHarmony

          • music
          • chords
          • scales
          • iOS
          • swift
          • App Store

          Problem

          I wrote the first version of iHarmony in 2008. It was the very first iOS app I gave birth to, combining my passion for music and programming. I remember buying an iPhone and my first Mac with the precise purpose of jumping on the apps train at a time

          Problem I wrote the first version of iHarmony in 2008. It was the very first iOS app I gave birth to, combining my passion for music and programming. I remember buying an iPhone and my first Mac with the precise purpose of jumping on the apps train at a time when it wasn't clear if the apps were there to stay or were just a temporary hype. But I did it, dropped my beloved Ubuntu to join a whole new galaxy. iHarmony was also one of the first 2000 apps on the App Store. Up until the recent rewrite, iHarmony was powered by a manually crafted database containing scales, chords, and harmonization I inputted. What-a-shame! I guess it made sense, I wanted to learn iOS and not to focus on implementing some core logic independent from the platform. Clearly a much better and less error-prone way to go would be to implement an algorithm to generate all the entries based on some DSL/spec. It took me almost 12 years to decide to tackle the problem and I've recently realized that writing the algorithm I wanted was harder than I thought. Also thought was a good idea give SwiftUI a try since the UI of iHarmony is extremely simple but... nope. Since someone on the Internet expressed interest 😉, I wrote this article to explain how I solved the problem of modeling music theory concepts in a way that allows the generation of any sort of scales, chords, and harmonization. I only show the code needed to get a grasp of the overall structure. I know there are other solutions ready to be used on GitHub but, while I don't particularly like any of them, the point of rewriting iHarmony from scratch was to challenge myself, not to reuse code someone else wrote. Surprisingly to me, getting to the solution described here took me 3 rewrites and 2 weeks. Solution The first fundamental building blocks to model are surely the musical notes, which are made up of a natural note and an accidental. enum NaturalNote: String { case C, D, E, F, G, A, B } enum Accidental: String { case flatFlatFlat = "bbb" case flatFlat = "bb" case flat = "b" case natural = "" case sharp = "#" case sharpSharp = "##" case sharpSharpSharp = "###" func applyAccidental(_ accidental: Accidental) throws -> Accidental {...} } struct Note: Hashable, Equatable { let naturalNote: NaturalNote let accidental: Accidental ... static let Dff = Note(naturalNote: .D, accidental: .flatFlat) static let Df = Note(naturalNote: .D, accidental: .flat) static let D = Note(naturalNote: .D, accidental: .natural) static let Ds = Note(naturalNote: .D, accidental: .sharp) static let Dss = Note(naturalNote: .D, accidental: .sharpSharp) ... func noteByApplyingAccidental(_ accidental: Accidental) throws -> Note {...} } Combinations of notes make up scales and chords and they are... many. What's fixed instead in music theory, and therefore can be hard-coded, are the keys (both major and minor) such as: C major: C, D, E, F, G, A, B A minor: A, B, C, D, E, F, G D major: D, E, F#, G, A, B, C# We'll get back to the keys later, but we can surely implement the note sequence for each musical key. typealias NoteSequence = [Note] extension NoteSequence { static let C = [Note.C, Note.D, Note.E, Note.F, Note.G, Note.A, Note.B] static let A_min = [Note.A, Note.B, Note.C, Note.D, Note.E, Note.F, Note.G] static let G = [Note.G, Note.A, Note.B, Note.C, Note.D, Note.E, Note.Fs] static let E_min = [Note.E, Note.Fs, Note.G, Note.A, Note.B, Note.C, Note.D] ... } Next stop: intervals. They are a bit more interesting as not every degree has the same types. Let's split into 2 sets: 2nd, 3rd, 6th and 7th degrees can be minor, major, diminished and augmented 1st (and 8th), 4th and 5th degrees can be perfect, diminished and augmented. We need to use different kinds of "diminished" and "augmented" for the 2 sets as later on we'll have to calculate the accidentals needed to turn an interval into another. Some examples: to get from 2nd augmented to 2nd diminished, we need a triple flat accidental (e.g. in C major scale, from D♯ to D♭♭ there are 3 semitones) to get from 5th augmented to 5th diminished, we need a double flat accidental (e.g. in C major scale, from G♯ to G♭there are 2 semitones) We proceed to hard-code the allowed intervals in music, leaving out the invalid ones (e.g. Interval(degree: ._2, type: .augmented)) enum Degree: Int, CaseIterable { case _1, _2, _3, _4, _5, _6, _7, _8 } enum IntervalType: Int, RawRepresentable { case perfect case minor case major case diminished case augmented case minorMajorDiminished case minorMajorAugmented } struct Interval: Hashable, Equatable { let degree: Degree let type: IntervalType static let _1dim = Interval(degree: ._1, type: .diminished) static let _1 = Interval(degree: ._1, type: .perfect) static let _1aug = Interval(degree: ._1, type: .augmented) static let _2dim = Interval(degree: ._2, type: .minorMajorDiminished) static let _2min = Interval(degree: ._2, type: .minor) static let _2maj = Interval(degree: ._2, type: .major) static let _2aug = Interval(degree: ._2, type: .minorMajorAugmented) ... static let _4dim = Interval(degree: ._4, type: .diminished) static let _4 = Interval(degree: ._4, type: .perfect) static let _4aug = Interval(degree: ._4, type: .augmented) ... static let _7dim = Interval(degree: ._7, type: .minorMajorDiminished) static let _7min = Interval(degree: ._7, type: .minor) static let _7maj = Interval(degree: ._7, type: .major) static let _7aug = Interval(degree: ._7, type: .minorMajorAugmented) } Now it's time to model the keys (we touched on them above already). What's important is to define the intervals for all of them (major and minor ones). enum Key { // natural case C, A_min // sharp case G, E_min case D, B_min case A, Fs_min case E, Cs_min case B, Gs_min case Fs, Ds_min case Cs, As_min // flat case F, D_min case Bf, G_min case Ef, C_min case Af, F_min case Df, Bf_min case Gf, Ef_min case Cf, Af_min ... enum KeyType { case naturalMajor case naturalMinor case flatMajor case flatMinor case sharpMajor case sharpMinor } var type: KeyType { switch self { case .C: return .naturalMajor case .A_min: return .naturalMinor case .G, .D, .A, .E, .B, .Fs, .Cs: return .sharpMajor case .E_min, .B_min, .Fs_min, .Cs_min, .Gs_min, .Ds_min, .As_min: return .sharpMinor case .F, .Bf, .Ef, .Af, .Df, .Gf, .Cf: return .flatMajor case .D_min, .G_min, .C_min, .F_min, .Bf_min, .Ef_min, .Af_min: return .flatMinor } } var intervals: [Interval] { switch type { case .naturalMajor, .flatMajor, .sharpMajor: return [ ._1, ._2maj, ._3maj, ._4, ._5, ._6maj, ._7maj ] case .naturalMinor, .flatMinor, .sharpMinor: return [ ._1, ._2maj, ._3min, ._4, ._5, ._6min, ._7min ] } } var notes: NoteSequence { switch self { case .C: return .C case .A_min: return .A_min ... } } At this point we have all the fundamental building blocks and we can proceed with the implementation of the algorithm. The idea is to have a function that given a key a root interval a list of intervals it works out the list of notes. In terms of inputs, it seems the above is all we need to correctly work out scales, chords, and - by extension - also harmonizations. Mind that the root interval doesn't have to be part of the list of intervals, that is simply the interval to start from based on the given key. Giving a note as a starting point is not good enough since some scales simply don't exist for some notes (e.g. G♯ major scale doesn't exist in the major key, and G♭minor scale doesn't exist in any minor key). Before progressing to the implementation, please consider the following unit tests that should make sense to you: func test_noteSequence_C_1() { let key: Key = .C let noteSequence = try! engine.noteSequence(customKey: key.associatedCustomKey, intervals: [._1, ._2maj, ._3maj, ._4, ._5, ._6maj, ._7maj]) let expectedValue: NoteSequence = [.C, .D, .E, .F, .G, .A, .B] XCTAssertEqual(noteSequence, expectedValue) } func test_noteSequence_withRoot_C_3maj_majorScaleIntervals() { let key = Key.C let noteSequence = try! engine.noteSequence(customKey: key.associatedCustomKey, rootInterval: ._3maj, intervals: [._1, ._2maj, ._3maj, ._4, ._5, ._6maj, ._7maj]) let expectedValue: NoteSequence = [.E, .Fs, .Gs, .A, .B, .Cs, .Ds] XCTAssertEqual(noteSequence, expectedValue) } func test_noteSequence_withRoot_Gsmin_3maj_alteredScaleIntervals() { let key = Key.Gs_min let noteSequence = try! engine.noteSequence(customKey: key.associatedCustomKey, rootInterval: ._3maj, intervals: [._1aug, ._2maj, ._3dim, ._4dim, ._5aug, ._6dim, ._7dim]) let expectedValue: NoteSequence = [.Bs, .Cs, .Df, .Ef, .Fss, .Gf, .Af] XCTAssertEqual(noteSequence, expectedValue) } and here is the implementation. Let's consider a simple case, so it's easier to follow: key = C major root interval = 3maj interval = major scale interval (1, 2maj, 3min, 4, 5, 6maj, 7min) if you music theory allowed you to understand the above unit tests, you would expect the output to be: E, F♯, G, A, B, C♯, D (which is a Dorian scale). Steps: we start by shifting the notes of the C key to position the 3rd degree (based on the 3maj) as the first element of the array, getting the note sequence E, F, G, A, B, C, D; here's the first interesting bit: we then get the list of intervals by calculating the number of semitones from the root to any other note in the sequence and working out the corresponding Interval: 1_perfect, 2_minor, 3_minor, 4_perfect, 5_perfect, 6_minor, 7_minor; we now have all we need to create a CustomKey which is pretty much a Key (with notes and intervals) but instead of being an enum with pre-defined values, is a struct; here's the second tricky part: return the notes by mapping the input intervals. Applying to each note in the custom key the accidental needed to match the desired interval. In our case, the only 2 intervals to 'adjust' are the 2nd and the 6th intervals, both minor in the custom key but major in the list of intervals. So we have to apply a sharp accidental to 'correct' them. 👀 I've used force unwraps in these examples for simplicity, the code might already look complex by itself. class CoreEngine { func noteSequence(customKey: CustomKey, rootInterval: Interval = ._1, intervals: [Interval]) throws -> NoteSequence { // 1. let noteSequence = customKey.shiftedNotes(by: rootInterval.degree) let firstNoteInShiftedSequence = noteSequence.first! // 2. let adjustedIntervals = try noteSequence.enumerated().map { try interval(from: firstNoteInShiftedSequence, to: $1, targetDegree: Degree(rawValue: $0)!) } // 3. let customKey = CustomKey(notes: noteSequence, intervals: adjustedIntervals) // 4. return try intervals.map { let referenceInterval = customKey.firstIntervalWithDegree($0.degree)! let note = customKey.notes[$0.degree.rawValue] let accidental = try referenceInterval.type.accidental(to: $0.type) return try note.noteByApplyingAccidental(accidental) } } } It's worth showing the implementation of the methods used above: private func numberOfSemitones(from sourceNote: Note, to targetNote: Note) -> Int { let notesGroupedBySameTone: [[Note]] = [ [.C, .Bs, .Dff], [.Cs, .Df, .Bss], [.D, .Eff, .Css], [.Ds, .Ef, .Fff], [.E, .Dss, .Ff], [.F, .Es, .Gff], [.Fs, .Ess, .Gf], [.G, .Fss, .Aff], [.Gs, .Af], [.A, .Gss, .Bff], [.As, .Bf, .Cff], [.B, .Cf, .Ass] ] let startIndex = notesGroupedBySameTone.firstIndex { $0.contains(sourceNote)}! let endIndex = notesGroupedBySameTone.firstIndex { $0.contains(targetNote)}! return endIndex >= startIndex ? endIndex - startIndex : (notesGroupedBySameTone.count - startIndex) + endIndex } private func interval(from sourceNote: Note, to targetNote: Note, targetDegree: Degree) throws -> Interval { let semitones = numberOfSemitones(from: sourceNote, to: targetNote) let targetType: IntervalType = try { switch targetDegree { case ._1, ._8: return .perfect ... case ._4: switch semitones { case 4: return .diminished case 5: return .perfect case 6: return .augmented default: throw CustomError.invalidConfiguration ... case ._7: switch semitones { case 9: return .minorMajorDiminished case 10: return .minor case 11: return .major case 0: return .minorMajorAugmented default: throw CustomError.invalidConfiguration } } }() return Interval(degree: targetDegree, type: targetType) } the Note's noteByApplyingAccidental method: func noteByApplyingAccidental(_ accidental: Accidental) throws -> Note { let newAccidental = try self.accidental.apply(accidental) return Note(naturalNote: naturalNote, accidental: newAccidental) } and the Accidental's apply method: func apply(_ accidental: Accidental) throws -> Accidental { switch (self, accidental) { ... case (.flat, .flatFlatFlat): throw CustomError.invalidApplicationOfAccidental case (.flat, .flatFlat): return .flatFlatFlat case (.flat, .flat): return .flatFlat case (.flat, .natural): return .flat case (.flat, .sharp): return .natural case (.flat, .sharpSharp): return .sharp case (.flat, .sharpSharpSharp): return .sharpSharp case (.natural, .flatFlatFlat): return .flatFlatFlat case (.natural, .flatFlat): return .flatFlat case (.natural, .flat): return .flat case (.natural, .natural): return .natural case (.natural, .sharp): return .sharp case (.natural, .sharpSharp): return .sharpSharp case (.natural, .sharpSharpSharp): return .sharpSharpSharp ... } With the above engine ready (and 💯﹪ unit tested!), we can now proceed to use it to work out what we ultimately need (scales, chords, and harmonizations). extension CoreEngine { func scale(note: Note, scaleIdentifier: Identifier) throws -> NoteSequence {...} func chord(note: Note, chordIdentifier: Identifier) throws -> NoteSequence {...} func harmonization(key: Key, harmonizationIdentifier: Identifier) throws -> NoteSequence {...} func chordSignatures(note: Note, scaleHarmonizationIdentifier: Identifier) throws -> [ChordSignature] {...} func harmonizations(note: Note, scaleHarmonizationIdentifier: Identifier) throws -> [NoteSequence] {...} } Conclusions There's more to it but with this post I only wanted to outline the overall idea. The default database is available on GitHub at albertodebortoli/iHarmonyDB. The format used is JSON and the community can now easily suggest additions. Here is how the definition of a scale looks: "scale_dorian": { "group": "group_scales_majorModes", "isMode": true, "degreeRelativeToMain": 2, "inclination": "minor", "intervals": [ "1", "2maj", "3min", "4", "5", "6maj", "7min" ] } and a chord: "chord_diminished": { "group": "group_chords_diminished", "abbreviation": "dim", "intervals": [ "1", "3min", "5dim" ] } and a harmonization: "scaleHarmonization_harmonicMajorScale4Tones": { "group": "group_harmonization_harmonic_major", "inclination": "major", "harmonizations": [ "harmonization_1_major7plus", "harmonization_2maj_minor7dim5", "harmonization_3maj_minor7", "harmonization_4_minor7plus", "harmonization_5_major7", "harmonization_6min_major7plus5sharp", "harmonization_7maj_diminished7" ] } Have to say, I'm pretty satisfied with how extensible this turned out to be. Thanks for reading 🎶

          The iOS internationalization basics I keep forgetting

          • iOS
          • formatting
          • date
          • currency
          • timezone
          • locale
          • language

          Localizations, locales, timezones, date and currency formatting... it's shocking how easy is to forget how they work and how to use them correctly. In this article, I try to summarize the bare minimum one needs to know to add internationalization support to an iOS app.

          In this article, I try to summarize the bare minimum one needs to know to add internationalization support to an iOS app. Localizations, locales, timezones, date and currency formatting... it's shocking how easy is to forget how they work and how to use them correctly. After years more than 10 years into iOS development, I decided to write down a few notes on the matter, with the hope that they will come handy again in the future, hopefully not only to me. TL;DR From Apple docs: Date: a specific point in time, independent of any calendar or time zone; TimeZone: information about standard time conventions associated with a specific geopolitical region; Locale: information about linguistic, cultural, and technological conventions for use in formatting data for presentation. Rule of thumb: All DateFormatters should use the locale and the timezone of the device; All NumberFormatter, in particular those with numberStyle set to .currency (for the sake of this article) should use a specific locale so that prices are not shown in the wrong currency. General notes on formatters Let's start by stating the obvious. Since iOS 10, Foundation (finally) provides ISO8601DateFormatter, which, alongside with DateFormatter and NumberFormatter, inherits from Formatter. Formatter locale property timeZone property ISO8601DateFormatter ❌ ✅ DateFormatter ✅ ✅ NumberFormatter ✅ ❌ In an app that only consumes data from an API, the main purpose of ISO8601DateFormatter is to convert strings to dates (String -> Date) more than the inverse. DateFormatter is then used to format dates (Date -> String) to ultimately show the values in the UI. NumberFormatter instead, converts numbers (prices in the vast majority of the cases) to strings (NSNumber/Decimal -> String). Formatting dates 🕗 🕝 🕟 It seems the following 4 are amongst the most common ISO 8601 formats, including the optional UTC offset. A: 2019-10-02T16:53:42 B: 2019-10-02T16:53:42Z C: 2019-10-02T16:53:42-02:00 D: 2019-10-02T16:53:42.974Z In this article I'll stick to these formats. The 'Z' at the end of an ISO8601 date indicates that it is in UTC, not a local time zone. Locales Converting strings to dates (String -> Date) is done using ISO8601DateFormatter objects set up with various formatOptions. Once we have a Date object, we can deal with the formatting for the presentation. Here, the locale is important and things can get a bit tricky. Locales have nothing to do with timezones, locales are for applying a format using a language/region. Locale identifiers are in the form of <language_identifier>_<region_identifier> (e.g. en_GB). We should use the user's locale when formatting dates (Date -> String). Consider a British user moving to Italy, the apps should keep showing a UI localized in English, and the same applies to the dates that should be formatted using the en_GB locale. Using the it_IT locale would show "2 ott 2019, 17:53" instead of the correct "2 Oct 2019 at 17:53". Locale.current, shows the locale set (overridden) in the iOS simulator and setting the language and regions in the scheme's options comes handy for debugging. Some might think that it's acceptable to use Locale.preferredLanguages.first and create a Locale from it with let preferredLanguageLocale = Locale(identifier: Locale.preferredLanguages.first!) and set it on the formatters. I think that doing so is not great since we would display dates using the Italian format but we won't necessarily be using the Italian language for the other UI elements as the app might not have the IT localization, causing an inconsistent experience. In short: don't use preferredLanguages, best to use Locale.current. Apple strongly suggests using en_US_POSIX pretty much everywhere (1, 2). From Apple docs: [...] if you're working with fixed-format dates, you should first set the locale of the date formatter to something appropriate for your fixed format. In most cases the best locale to choose is "en_US_POSIX", a locale that's specifically designed to yield US English results regardless of both user and system preferences. "en_US_POSIX" is also invariant in time (if the US, at some point in the future, changes the way it formats dates, "en_US" will change to reflect the new behaviour, but "en_US_POSIX" will not), and between machines ("en_US_POSIX" works the same on iOS as it does on OS X, and as it it does on other platforms). Once you've set "en_US_POSIX" as the locale of the date formatter, you can then set the date format string and the date formatter will behave consistently for all users. I couldn't find a really valid reason for doing so and quite frankly using the device locale seems more appropriate for converting dates to strings. Here is the string representation for the same date using different locales: en_US_POSIX: May 2, 2019 at 3:53 PM en_GB: 2 May 2019 at 15:53 it_IT: 2 mag 2019, 15:53 The above should be enough to show that en_US_POSIX is not what we want to use in this case, but it has more to do with maintaining a standard for communication across machines. From this article: "[...] Unless you specifically need month and/or weekday names to appear in the user's language, you should always use the special locale of en_US_POSIX. This will ensure your fixed format is actually fully honored and no user settings override your format. This also ensures month and weekday names appear in English. Without using this special locale, you may get 24-hour format even if you specify 12-hour (or visa-versa). And dates sent to a server almost always need to be in English." Timezones Stating the obvious one more time: Greenwich Mean Time (GMT) is a time zone while Coordinated Universal Time (UTC) is a time standard. There is no time difference between them. Timezones are fundamental to show the correct date/time in the final text shown to the user. The timezone value is taken from macOS and the iOS simulator inherits it, meaning that printing TimeZone.current, shows the timezone set in the macOS preferences (e.g. Europe/Berlin). Show me some code Note that in the following example, we use GMT (Greenwich Mean Time) and CET (Central European Time), which is GMT+1. Mind that it's best to reuse formatters since the creation is expensive. class CustomDateFormatter { private let dateFormatter: DateFormatter = { let dateFormatter = DateFormatter() dateFormatter.dateStyle = .medium dateFormatter.timeStyle = .short return dateFormatter }() private let locale: Locale private let timeZone: TimeZone init(locale: Locale = .current, timeZone: TimeZone = .current) { self.locale = locale self.timeZone = timeZone } func string(from date: Date) -> String { dateFormatter.locale = locale dateFormatter.timeZone = timeZone return dateFormatter.string(from: date) } } let stringA = "2019-11-02T16:53:42" let stringB = "2019-11-02T16:53:42Z" let stringC = "2019-11-02T16:53:42-02:00" let stringD = "2019-11-02T16:53:42.974Z" // The ISO8601DateFormatter's extension (redacted) // internally uses multiple formatters, each one set up with different // options (.withInternetDateTime, .withFractionalSeconds, withFullDate, .withTime, .withColonSeparatorInTime) // to be able to parse all the formats. // timeZone property is set to GMT. let dateA = ISO8601DateFormatter.date(from: stringA)! let dateB = ISO8601DateFormatter.date(from: stringB)! let dateC = ISO8601DateFormatter.date(from: stringC)! let dateD = ISO8601DateFormatter.date(from: stringD)! var dateFormatter = CustomDateFormatter(locale: Locale(identifier: "en_GB"), timeZone: TimeZone(identifier: "GMT")!) dateFormatter.string(from: dateA) // 2 Nov 2019 at 16:53 dateFormatter.string(from: dateB) // 2 Nov 2019 at 16:53 dateFormatter.string(from: dateC) // 2 Nov 2019 at 18:53 dateFormatter.string(from: dateD) // 2 Nov 2019 at 16:53 dateFormatter = CustomDateFormatter(locale: Locale(identifier: "it_IT"), timeZone: TimeZone(identifier: "CET")!) dateFormatter.string(from: dateA) // 2 nov 2019, 17:53 dateFormatter.string(from: dateB) // 2 nov 2019, 17:53 dateFormatter.string(from: dateC) // 2 nov 2019, 19:53 dateFormatter.string(from: dateD) // 2 nov 2019, 17:53 Using the CET timezone also for ISO8601DateFormatter, the final string produced for dateA would respectively be "15:53" when formatted with GMT and "16:53" when formatted with CET. As long as the string passed to ISO8601DateFormatter is in UTC, it's irrelevant to set the timezone on the formatter. Apple suggests to set the timeZone property to UTC with TimeZone(secondsFromGMT: 0), but this is irrelevant if the string representing the date already includes the timezone. If your server returns a string representing a date that is not in UTC, it's probably because of one of the following 2 reasons: it's not meant to be in UTC (questionable design decision indeed) and therefore the timezone of the device should be used instead; the backend developers implemented it wrong and they should add the 'Z 'at the end of the string if what they intended is to have the date in UTC. In short: All DateFormatters should have timezone and locale set to .current and avoid handling non-UTC string if possible. Formatting currencies € $ ¥ £ The currency symbol and the formatting of a number should be defined via a Locale, and they shouldn't be set/changed on the NumberFormatter. Don't use the user's locale (Locale.current) because it could be set to a region not supported by the app. Let's consider the example of a user's locale to be en_US, and the app to be available only for the Italian market. We must set a locale Locale(identifier: "it_IT") on the formatter, so that: prices will be shown only in Euro (not American Dollar) the format used will be the one of the country language (for Italy, "12,34 €", not any other variation such as "€12.34") class CurrencyFormatter { private let locale: Locale init(locale: Locale = .current) { self.locale = locale } func string(from decimal: Decimal, overriddenCurrencySymbol: String? = nil) -> String { let formatter = NumberFormatter() formatter.numberStyle = .currency if let currencySymbol = overriddenCurrencySymbol { // no point in doing this on a NumberFormatter ❌ formatter.currencySymbol = currencySymbol } formatter.locale = locale return formatter.string(from: decimal as NSNumber)! } } let itCurrencyFormatter = CurrencyFormatter(locale: Locale(identifier: "it_IT")) let usCurrencyFormatter = CurrencyFormatter(locale: Locale(identifier: "en_US")) let price1 = itCurrencyFormatter.string(from: 12.34) // "12,34 €" ✅ let price2 = usCurrencyFormatter.string(from: 12.34) // "$12.34" ✅ let price3 = itCurrencyFormatter.string(from: 12.34, overriddenCurrencySymbol: "₿") // "12,34 ₿" ❌ let price4 = usCurrencyFormatter.string(from: 12.34, overriddenCurrencySymbol: "₿") // "₿ 12.34" ❌ In short: All NumberFormatters should have the locale set to the one of the country targeted and no currencySymbol property overridden (it's inherited from the locale). Languages 🇬🇧 🇮🇹 🇳🇱 Stating the obvious one more time, but there are very rare occasions that justify forcing the language in the app: func setLanguage(_ language: String) { let userDefaults = UserDefaults.standard userDefaults.set([language], forKey: "AppleLanguages") } The above circumvents the Apple localization mechanism and needs an app restart, so don't do it and localize the app by the book: add localizations in Project -> Localizations; create a Localizable.strings file and tap the localize button in the inspector; always use NSLocalizedString() in code. Let's consider this content of Localizable.strings (English): "kHello" = "Hello"; "kFormatting" = "Some formatting 1. %@ 2. %d."; and this for another language (e.g. Italian) Localizable.strings (Italian): "kHello" = "Ciao"; "kFormatting" = "Esempio di formattazione 1) %@ 2) %d."; Simple localization Here's the trivial example: let localizedString = NSLocalizedString("kHello", comment: "") If Locale.current.languageCode is it, the value would be 'Ciao', and 'Hello' otherwise. Formatted localization For formatted strings, use the following: let stringWithFormats = NSLocalizedString("kFormatting", comment: "") String.localizedStringWithFormat(stringWithFormats, "some value", 3) As before, if Locale.current.languageCode is it, value would be 'Esempio di formattazione 1) some value 2) 3.', and 'Some formatting 1) some value 2) 3.' otherwise. Plurals localization For plurals, create a Localizable.stringsdict file and tap the localize button in the inspector. Localizable.strings and Localizable.stringsdict are independent, so there are no cross-references (something that often tricked me). Here is a sample content: <dict> <key>kPlurality</key> <dict> <key>NSStringLocalizedFormatKey</key> <string>Interpolated string: %@, interpolated number: %d, interpolated variable: %#@COUNT@.</string> <key>COUNT</key> <dict> <key>NSStringFormatSpecTypeKey</key> <string>NSStringPluralRuleType</string> <key>NSStringFormatValueTypeKey</key> <string>d</string> <key>zero</key> <string>nothing</string> <key>one</key> <string>%d object</string> <key>two</key> <string></string> <key>few</key> <string></string> <key>many</key> <string></string> <key>other</key> <string>%d objects</string> </dict> </dict> </dict> Localizable.stringsdict undergo the same localization mechanism of its companion Localizable.strings. It's mandatory to only implement 'other', but an honest minimum includes 'zero', 'one', and 'other'. Given the above content, the following code should be self-explanatory: let localizedHello = NSLocalizedString("kHello", comment: "") // from Localizable.strings let stringWithPlurals = NSLocalizedString("kPlurality", comment: "") // from Localizable.stringsdict String.localizedStringWithFormat(stringWithPlurals, localizedHello, 42, 1) With the en language, the value would be 'Interpolated string: Hello, interpolated number: 42, interpolated variable: 1 object.'. Use the scheme's option to run with a specific Application Language (it will change the current locale language and therefore also the output of the DateFormatters). If the language we've set or the device language are not supported by the app, the system falls back to en. References https://en.wikipedia.org/wiki/ISO_8601 https://nsdateformatter.com/ https://foragoodstrftime.com/ https://epochconverter.com/ So... that's all folks. 🌍

          Modular iOS Architecture @ Just Eat

          • iOS
          • Just Eat
          • architecture
          • modulrization
          • Cocoapods

          The journey towards a modular architecture taken by the Just Eat iOS team.

          The journey we took to restructure our mobile apps towards a modular architecture. Originally published on the Just Eat Engineering Blog. Overview Modular mobile architectures have been a hot topic over the past 2 years, counting a plethora of articles and conference talks. Almost every big company promoted and discussed modularization publicly as a way to scale big projects. At Just Eat, we jumped on the modular architecture train probably before it was mainstream and, as we'll discuss in this article, the root motivation was quite peculiar in the industry. Over the years (2016-2019), we've completely revamped our iOS products from the ground up and learned a lot during this exciting and challenging journey. There is so much to say about the way we structured our iOS stack that it would probably deserve a series of articles, some of which have previously been posted. Here we summarize the high-level iOS architecture we crafted, covering the main aspects in a way concise enough for the reader to get a grasp of them and hopefully learn some valuable tips. Modular Architecture Lots of information can be found online on modular architectures. In short: A modular architecture is a software design technique that emphasizes separating the functionality of a program into independent, interchangeable modules, such that each one contains everything necessary to execute only one aspect of the desired functionality. Note that modular design applies to the code you own. A project with several third-party dependencies but no sensible separation for the code written by your team is not considered modular. A modular design is more about the principle rather than the specific technology. One could achieve it in a variety of ways and with different tools. Here are some key points and examples that should inform the decision of the ifs and the hows of implementing modularization: Business reasons The company requires that parts of the codebase are reused and shared across projects, products, and teams; The company requires multiple products to be unified into a single one. Tech reasons The codebase has grown to a state where things become harder and harder to maintain and to iterate over; Development is slowed down due to multiple developers working on the same monolithic codebase; Besides reusing code, you need to port functionalities across projects/products. Multiple teams The company structured teams following strategic models (e.g. Spotify model) and functional teams only work on a subset of the final product; Ownership of small independent modules distributed across teams enables faster iterations; The much smaller cognitive overhead of working on a smaller part of the whole product can vastly simplify the overall development. Pre-existing knowledge Members of the team might already be familiar with specific solutions (Carthage, CocoaPods, Swift Package Manager, manual frameworks setup within Xcode). In the case of a specific familiarity with a system, it's recommended to start with it since all solutions come with pros and cons and there's not a clear winner at the time of writing. Modularizing code (if done sensibly) is almost always a good thing: it enforces separation of concerns, keeps complexity under control, allows faster development, etc. It has to be said that it's not necessarily what one needs for small projects and its benefits become tangible only after a certain complexity threshold is crossed. Journey to a new architecture In 2014, Just Eat was a completely different environment from today and back then the business decided to split the tech department into separate departments: one for UK and one for the other countries. While this was done with the best intentions to allow faster evolution in the main market (UK), it quickly created a hard division between teams, services, and people. In less than 6 months, the UK and International APIs and consumer clients deeply diverged introducing country-specific logic and behaviors. By mid-2016 the intent of "merging back" into a single global platform was internally announced and at that time it almost felt like a company acquisition. This is when we learned the importance of integrating people before technology. The teams didn’t know each other very well and became reasonably territorial on their codebase. It didn’t help that the teams span multiple cities. It's understandable that getting to an agreement on how going back to a single, global, and unified platform took months. The options we considered spanned from rewriting the product from scratch to picking one of the two existing ones and make it global. A complete rewrite would have eventually turned out to be a big-bang release with the risk of regressions being too high; not something sensible or safe to pursue. Picking one codebase over the other would have necessarily let down one of the two teams and caused the re-implementation of some missing features present in the other codebase. At that time, the UK project was in a better shape and new features were developed for the UK market first. The international project was a bit behind due to the extra complexity of supporting multiple countries and features being too market-specific. During that time, the company was also undergoing massive growth and with multiple functional teams having been created internally, there was an increasing need to move towards modularization. Therefore, we decided to gradually and strategically modularize parts of the mobile products and onboard them onto the other codebase in a controlled and safe way. In doing so, we took the opportunity to deeply refactor and, in the vast majority of the cases, rewrite parts in their entirety enabling new designs, better tests, higher code coverage, and - holistically - a fully Swift codebase. We knew that the best way to refactor and clean up the code was by following a bottom-up approach. We started with the foundations to solve small and well-defined problems - such as logging, tracking, theming - enabling the team to learn to think modular. We later moved to isolating big chunks of code into functional modules to be able to onboard them into the companion codebase and ship them on a phased rollout. We soon realized we needed a solid engine to handle run-time configurations and remote feature flagging to allow switching ON and OFF features as well as entire modules. As discussed in a previous article, we developed JustTweak to achieve this goal. At the end of the journey, the UK and the International projects would look very similar, sharing a number of customizable modules, and differing only in the orchestration layer in the apps. The Just Eat iOS apps are far bigger and more complex than they might look at first glance. Generically speaking, merging different codebases takes orders of magnitude longer than separating them, and for us, it was a process that took over 3 years, being possible thanks to unparalleled efforts of engineers brought to work together. Over this time, the whole team learned a lot, from the basics of developing code in isolation to how to scale a complex system. Holistic Design 🤘 The following diagram outlines the modular architecture in its entirety as it is at the time of writing this article (December 2019). We can appreciate a fair number of modules clustered by type and the different consumer apps. Modular iOS architecture - holistic design Whenever possible, we took the opportunity to abstract some modules having them in a state that allows open-sourcing the code. All of our open-source modules are licensed under Apache 2 and can be found at github.com/justeat. Apps Due to the history of Just Eat described above, we build different apps per country per brand from different codebases All the modularization work we did bottom-up brought us to a place where the apps differ only in the layer orchestrating the modules. With all the consumer-facing features been moved to the domain modules, there is very little code left in the apps. Domain Modules Domain modules contain features specific to an area of the product. As the diagram above shows, the sum of all those parts makes up the Just Eat apps. These modules are constantly modified and improved by our teams and updating the consumer apps to use newer versions is an explicit action. We don't particularly care about backward compatibility here since we are the sole consumers and it's common to break the public interface quite often if necessary. It might seem at first that domain modules should depend on some Core modules (e.g. APIClient) but doing so would complicate the dependency tree as we'll discuss further in the "Dependency Management" section of this article. Instead, we inject core modules' services, simply making them conformant to protocols defined in the domain module. In this way, we maintain a good abstraction and avoid tangling the dependency graph. Core & Shared modules The Core and Shared modules represent the foundations of our stack, things like: custom UI framework theming engine logging, tracking, and analytics libraries test utilities client for all the Just Eat APIs feature flagging and experimentation engine and so forth. These modules - which are sometimes also made open-source - should not change frequently due to their nature. Here backward compatibility is important and we deprecate old APIs when introducing new ones. Both apps and domain modules can have shared modules as dependencies, while core modules can only be used by the apps. Updating the backbone of a system requires the propagation of the changes up in the stack (with its maintenance costs) and for this reason, we try to keep the number of shared modules very limited. Structure of a module As we touched on in previous articles, one of our fundamental principles is "always strive to find solutions to problems that are scalable and hide complexity as much as possible". We are almost obsessed with making things as simple as they can be. When building a module, our root principle is: Every module should be well tested, maintainable, readable, easily pluggable, and reasonably documented. The order of the adjectives implies some sort of priority. First of all, the code must be unit tested, and in the case of domain modules, UI tests are required too. Without reasonable code coverage, no code is shipped to production. This is the first step to code maintainability, where maintainable code is intended as "code that is easy to modify or extend". Readability is down to reasonable design, naming convention, coding standards, formatting, and all that jazz. Every module exposes a Facade that is very succinct, usually no more than 200 lines long. This entry point is what makes a module easily pluggable. In our module blueprint, the bare minimum is a combination of a facade class, injected dependencies, and one or more configuration objects driving the behavior of the module (leveraging the underlying feature flagging system powered by JustTweak discussed in a previous article). The facade should be all a developer needs to know in order to consume a module without having to look at implementation details. Just to give you an idea, here is an excerpt from the generated public interface of the Account module (not including the protocols): public typealias PasswordManagementService = ForgottenPasswordServiceProtocol & ResetPasswordServiceProtocol public typealias AuthenticationService = LoginServiceProtocol & SignUpServiceProtocol & PasswordManagementService & RecaptchaServiceProtocol public typealias UserAccountService = AccountInfoServiceProtocol & ChangePasswordServiceProtocol & ForgottenPasswordServiceProtocol & AccountCreditServiceProtocol public class AccountModule { public init(settings: Settings, authenticationService: AuthenticationService, userAccountService: UserAccountService, socialLoginServices: [SocialLoginService], userInfoProvider: UserInfoProvider) public func startLogin(on viewController: UIViewController) -> FlowCoordinator public func startResetPassword(on viewController: UIViewController, token: Token) -> FlowCoordinator public func startAccountInfo(on navigationController: UINavigationController) -> FlowCoordinator public func startAccountCredit(on navigationController: UINavigationController) -> FlowCoordinator public func loginUsingSharedWebCredentials(handler: @escaping (LoginResult) -> Void) } Domain module public interface example (Account module) We believe code should be self-descriptive and we tend to put comments only on code that really deserves some explanation, very much embracing John Ousterhout's approach described in A Philosophy of Software Design. Documentation is mainly relegated to the README file and we treat every module as if it was an open-source project: the first thing consumers would look at is the README file, and so we make it as descriptive as possible. Overall design We generate all our modules using CocoaPods via $ pod lib create which creates the project with a standard template generating the Podfile, podspec, and demo app in a breeze. The podspec could specify additional dependencies (both third-party and Core modules) that the demo app's Podfile could specify core modules dependencies alongside the module itself which is treated as a development pod as per standard setup. The backbone of the module, which is the framework itself, encompasses both business logic and UI meaning that both source and asset files are part of it. In this way, the demo apps are very much lightweight and only showcase module features that are implemented in the framework. The following diagram should summarize it all. Design of a module with Podfile and podspec examples Demo Apps Every module comes with a demo app we give particular care to. Demo apps are treated as first-class citizens and the stakeholders are both engineers and product managers. They massively help to showcase the module features - especially those under development - vastly simplify collaboration across Engineering, Product, and Design, and force a good mock-based test-first approach. Following is a SpringBoard page showing our demo apps, very useful to individually showcase all the functionalities implemented over time, some of which might not surface in the final product to all users. Some features are behind experiments, some still in development, while others might have been retired but still present in the modules. Every demo app has a main menu to: access the features force a specific language toggle configuration flags via JustTweak customize mock data We show the example of the Account module demo app on the right. Domain modules demo apps Internal design It's worth noting that our root principle mentioned above does not include any reference to the internal architecture of a module and this is intentional. It's common for iOS teams in the industry to debate on which architecture to adopt across the entire codebase but the truth is that such debate aims to find an answer to a non-existing problem. With an increasing number of modules and engineers, it's fundamentally impossible to align on a single paradigm shared and agreed upon by everyone. Betting on a single architectural design would ultimately let down some engineers who would complain down the road that a different design would have played out better. We decided to stick with the following rule of thumb: Developers are free to use the architectural design they feel would work better for a given problem. This approach brought us to have a variety of different designs - spanning from simple old-school MVC, to a more evolved VIPER - and we constantly learn from each other's code. What's important at the end of the day is that techniques such as inversion of control, dependency injection, and more generally the SOLID principles, are used appropriately to embrace our root principle. Dependency Management We rely heavily on CocoaPods since we adopted it in the early days as it felt like the best and most mature choice at the time we started modularizing our codebase. We think this still holds at the time of writing this article but we can envision a shift to SPM (Swift Package Manager) in 1-2 years time. With a growing number of modules, comes the responsibility of managing the dependencies between them. No panacea can cure dependency hell, but one should adopt some tricks to keep the complexity of the stack under reasonable control. Here's a summary of what worked for us: Always respect semantic versioning; Keep the dependency graph as shallow as possible. From our apps to the leaves of the graph there are no more than 2 levels; Use a minimal amount of shared dependencies. Be aware that every extra level with shared modules brings in higher complexity; Reduce the number of third-party libraries to the bare minimum. Code that's not written and owned by your team is not under your control; Never make modules within a group (domain, core, shared) depend on other modules of the same group; Automate the publishing of new versions. When a pull request gets merged into the master branch, it must also contain a version change in the podspec. Our continuous integration system will automatically validate the podspec, publish it to our private spec repository, and in just a matter of minutes the new version becomes available; Fix the version for dependencies in the Podfile. Whether it is a consumer app or a demo app, we want both our modules and third-party libraries not to be updated unintentionally. It's acceptable to use the optimistic operator for third-party libraries to allow automatic updates of new patch versions; Fix the version for third-party libraries in the modules' podspec. This guarantees that modules' behavior won't change in the event of changes in external libraries. Failing to do so would allow defining different versions in the app's Podfile, potentially causing the module to not function correctly or even to not compile; Do not fix the version for shared modules in the modules' podspec. In this way, we let the apps define the version in the Podfile, which is particularly useful for modules that change often, avoiding the hassle of updating the version of the shared modules in every podspec referencing it. If a new version of a shared module is not backward compatible with the module consuming it, the failure would be reported by the continuous integration system as soon as a new pull request gets raised. A note on the Monorepo approach When it comes to dependency management it would be unfair not to mention the opinable monorepo approach. Monorepos have been discussed quite a lot by the community to pose a remedy to dependency management (de facto ignoring it), some engineers praise them, others are quite contrary. Facebook, Google, and Uber are just some of the big companies known to have adopted this technique, but in hindsight, it's still unclear if it was the best decision for them. In our opinion, monorepos can sometimes be a good choice. For example, in our case, a great benefit a monorepo would give us is the ability to prepare a single pull request for both implementing a code change in a module and integrating it into the apps. This will have an even greater impact when all the Just Eat consumer apps are globalized into a single codebase. Onwards and upwards Modularizing the iOS product has been a long journey and the learnings were immense. All in all, it took more than 3 years, from May 2016 to October 2019, always balancing tech and product improvements. Our natural next step is unifying the apps into a single global project, migrating the international countries over to the UK project to ultimately reach the utopian state of having a single global app. All the modules have been implemented in a fairly abstract way and following a white labeling approach, allowing us to extend support to new countries and onboard acquired companies in the easiest possible way.

          Lessons learned from handling JWT on mobile

          • iOS
          • Authorization
          • JWT
          • Token
          • mobile

          Implementing Authorization on mobile can be tricky. Here are some recommendations to avoid common issues.

          Originally published on the Just Eat Engineering Blog.

          Overview

          Modern mobile apps are more complicated than they used to be back in the early days and developers have to face a variety of interesting problems.

          Implementing Authorization on mobile can be tricky. Here are some recommendations to avoid common issues. Originally published on the Just Eat Engineering Blog. Overview Modern mobile apps are more complicated than they used to be back in the early days and developers have to face a variety of interesting problems. While we've put in our two cents on some of them in previous articles, this one is about authorization and what we have learned by handling JWT on mobile at Just Eat. When it comes to authorization, it's standard practice to rely on OAuth 2.0 and the companion JWT (JSON Web Token). We found this important topic was rarely discussed online while much attention was given to new proposed implementations of network stacks, maybe using recent language features or frameworks such as Combine. We'll illustrate the problems we faced at Just Eat for JWT parsing, usage, and (most importantly) refreshing. You should be able to learn a few things on how to make your app more stable by reducing the chance of unauthorized requests allowing your users to virtually always stay logged in. What is JWT JWT stands for JSON Web Token and is an open industry standard used to represent claims transferred between two parties. A signed JWT is known as a JWS (JSON Web Signature). In fact, a JWT has either to be JWS or JWE (JSON Web Encryption). RFC 7515, RFC 7516, and RFC 7519 describe the various fields and claims in detail. What is relevant for mobile developers is the following: JWT is composed of 3 parts dot-separated: Header, Payload, Signature. The Payload is the only relevant part. The Header identifies which algorithm is used to generate the signature. There are reasons for not verifying the signature client-side making the Signature part irrelevant too. JWT has an expiration date. Expired tokens should be renewed/refreshed. JWT can contain any number of extra information specific to your service. It's common practice to store JWTs in the app keychain. Here is a valid and very short token example, courtesy of jwt.io/ which we recommend using to easily decode tokens for debugging purposes. It shows 3 fragments (base64 encoded) concatenated with a dot. eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyLCJleHAiOjE1Nzc3NTA0MDB9.7hgBhNK_ZpiteB3GtLh07KJ486Vfe3WAdS-XoDksJCQ The only field relevant to this document is exp (Expiration Time), part of Payload (the second fragment). This claim identifies the time after which the JWT must not be accepted. In order to accept a JWT, it's required that the current date/time must be before the expiration time listed in the exp claim. It's accepted practice for implementers to consider for some small leeway, usually no more than a few minutes, to account for clock skew. N.B. Some API calls might demand the user is logged in (user-authenticated calls), and others don't (non-user-authenticated calls). JWT can be used in both cases, marking a distinction between Client JWT and User JWT we will refer to later on. The token refresh problem By far the most significant problem we had in the past was the renewal of the token. This seems to be something taken for granted by the mobile community, but in reality, we found it to be quite a fragile part of the authentication flow. If not done right, it can easily cause your customers to end up being logged out, with the consequent frustration we all have experienced as app users. The Just Eat app makes multiple API calls at startup: it fetches the order history to check for in-flight orders, fetches the most up-to-date consumer details, etc. If the token is expired when the user runs the app, a nasty race condition could cause the same refresh token to be used twice, causing the server to respond with a 401 and subsequently logging the user out on the app. This can also happen during normal execution when multiple API calls are performed very close to each other and the token expires prior to those. It gets trickier if the client and the server clocks are sensibly off sync: while the client might believe to be in possession of a valid token, it has already expired. The following diagram should clarify the scenario. Common misbehavior I couldn't find a company (regardless of size) or indie developer who had implemented a reasonable token refresh mechanism. The common approach seems to be: to refresh the token whenever an API call fails with 401 Unauthorized. This is not only causing an extra call that could be avoided by locally checking if the token has expired, but it also opens the door for the race condition illustrated above. Avoid race conditions when refreshing the token 🚦 We'll explain the solution with some technical details and code snippets but what what's more important is that the reader understands the root problem we are solving and why it should be given the proper attention. The more we thought about it, we more we convinced ourselves that the best way to shield ourselves from race conditions is by using threading primitives when scheduling async requests to fetch a valid token. This means that all the calls would be regulated via a filter that would hold off subsequent calls to fire until a valid token is retrieved, either from local storage or, if a refresh is needed, from the remote OAuth server. We'll show examples for iOS, so we've chosen dispatch queues and semaphores (using GCD); fancier and more abstract ways of implementing the solution might exist - in particular by leveraging modern FRP techniques - but ultimately the same primitives are used. For simplicity, let's assume that only user-authenticated API requests need to provide a JWT, commonly put in the Authorization header: Authorization: Bearer <jwt-token> The code below implements the "Get valid JWT" box from the following flowchart. The logic within this section is the one that must be implemented in mutual exclusion, in our solution, by using the combination of a serial queue and a semaphore. Here is just the minimum amount of code (Swift) needed to explain the solution. typealias Token = String typealias AuthorizationValue = String struct UserAuthenticationInfo { let bearerToken: Token // the JWT let refreshToken: Token let expiryDate: Date // computed on creation from 'exp' claim var isValid: Bool { return expiryDate.compare(Date()) == .orderedDescending } } protocol TokenRefreshing { func refreshAccessToken(_ refreshToken: Token, completion: @escaping (Result<UserAuthenticationInfo, Error>) -> Void) } protocol AuthenticationInfoStorage { var userAuthenticationInfo: UserAuthenticationInfo? func persistUserAuthenticationInfo(_ authenticationInfo: UserAuthenticationInfo?) func wipeUserAuthenticationInfo() } class AuthorizationValueProvider { private let authenticationInfoStore: AuthenticationInfoStorage private let tokenRefreshAPI: TokenRefreshing private let queue = DispatchQueue(label: <#label#>, qos: .userInteractive) private let semaphore = DispatchSemaphore(value: 1) init(tokenRefreshAPI: TokenRefreshing, authenticationInfoStore: AuthenticationInfoStorage) { self.tokenRefreshAPI = tokenRefreshAPI self.authenticationInfoStore = authenticationInfoStore } func getValidUserAuthorization(completion: @escaping (Result<AuthorizationValue, Error>) -> Void) { queue.async { self.getValidUserAuthorizationInMutualExclusion(completion: completion) } } } Before performing any user-authenticated request, the network client asks an AuthorizationValueProvider instance to provide a valid user Authorization value (the JWT). It does so via the async method getValidUserAuthorization which uses a serial queue to handle the requests. The chunky part is the getValidUserAuthorizationInMutualExclusion. private func getValidUserAuthorizationInMutualExclusion(completion: @escaping (Result<AuthorizationValue, Error>) -> Void) { semaphore.wait() guard let authenticationInfo = authenticationInfoStore.userAuthenticationInfo else { semaphore.signal() let error = // forge an error for 'missing authorization' completion(.failure(error)) return } if authenticationInfo.isValid { semaphore.signal() completion(.success(authenticationInfo.bearerToken)) return } tokenRefreshAPI.refreshAccessToken(authenticationInfo.refreshToken) { result in switch result { case .success(let authenticationInfo): self.authenticationInfoStore.persistUserAuthenticationInfo(authenticationInfo) self.semaphore.signal() completion(.success(authenticationInfo.bearerToken)) case .failure(let error) where error.isClientError: self.authenticationInfoStore.wipeUserAuthenticationInfo() self.semaphore.signal() completion(.failure(error)) case .failure(let error): self.semaphore.signal() completion(.failure(error)) } } } The method could fire off an async call to refresh the token, and this makes the usage of the semaphore crucial. Without it, the next request to AuthorizationValueProvider would be popped from the queue and executed before the remote refresh completes. The semaphore is initialised with a value of 1, meaning that only one thread can access the critical section at a given time. We make sure to call wait at the beginning of the execution and to call signal only when we have a result and therefore ready to leave the critical section. If the token found in the local store is still valid, we simply return it, otherwise, it's time to request a new one. In the latter case, if all goes well, we persist the token locally and allow the next request to access the method, in the case of an error, we should be careful and wipe the token only if the error is a legit client error (2xx range). This includes also the usage of a refresh token that is not valid anymore, which could happen, for instance, if the user resets the password on another platform/device. It's critical to not delete the token from the local store in the case of any other error, such as 5xx or the common Foundation's NSURLErrorNotConnectedToInternet (-1009), or else the user would unexpectedly be logged out. It's also important to note that the same AuthorizationValueProvider instance must be used by all the calls: using different ones would mean using different queues making the entire solution ineffective. It seemed clear that the network client we developed in-house had to embrace JWT refresh logic at its core so that all the API calls, even new ones that will be added in the future would make use of the same authentication flow. General recommendations Here are a couple more (minor) suggestions we thought are worth sharing since they might save you implementation time or influence the design of your solution. Correctly parse the Payload Another problem - even though quite trivial and that doesn't seem to be discussed much - is the parsing of the JWT, that can fail in some cases. In our case, this was related to the base64 encoding function and "adjusting" the base64 payload to be parsed correctly. In some implementations of base64, the padding character is not needed for decoding, since the number of missing bytes can be calculated but in Foundation's implementation it is mandatory. This caused us some head-scratching and this StackOverflow answer helped us. The solution is - more officially - stated in RFC 7515 - Appendix C and here is the corresponding Swift code: func base64String(_ input: String) -> String { var base64 = input .replacingOccurrences(of: "-", with: "+") .replacingOccurrences(of: "_", with: "/") switch base64.count % 4 { case 2: base64 = base64.appending("==") case 3: base64 = base64.appending("=") default: break } return base64 } The majority of the developers rely on external libraries to ease the parsing of the token, but as we often do, we have implemented our solution from scratch, without relying on a third-party library. Nonetheless, we feel JSONWebToken by Kyle Fuller is a very good one and it seems to implement JWT faithfully to the RFC, clearly including the necessary base64 decode function. Handle multiple JWT for multiple app states As previously stated, when using JWT as an authentication method for non-user- authenticated calls, we need to cater for at least 3 states, shown in the following enum: enum AuthenticationStatus { case notAuthenticated case clientAuthenticated case userAuthenticated } On a fresh install, we can expect to be in the .notAuthenticated state, but as soon as the first API call is ready to be performed, a valid Client JWT has to be fetched and stored locally (at this stage, other authentication mechanisms are used, most likely Basic Auth), moving to the .clientAuthenticated state. Once the user completes the login or signup procedure, a User JWT is retrieved and stored locally (but separately to the Client JWT), entering the .userAuthenticated, so that in the case of a logout we are left with a (hopefully still valid) Client JWT. In this scenario, almost all transitions are possible: A couple of recommendations here: if the user is logged in is important to use the User JWT also for the non-user-authenticated calls as the server may personalise the response (e.g. the list of restaurants in the Just Eat app) store both Client and User JWT, so that if the user logs out, the app is left with the Client JWT ready to be used to perform non-user-authenticated requests, saving an unnecessary call to fetch a new token Conclusion In this article, we've shared some learnings from handling JWT on mobile that are not commonly discussed within the community. As a good practice, it's always best to hide complexity and implementation details. Baking the refresh logic described above within your API client is a great way to avoid developers having to deal with complex logic to provide authorization, and enables all the API calls to undergo the same authentication mechanism. Consumers of an API client, should not have the ability to gather the JWT as it’s not their concern to use it or to fiddle with it. We hope this article helps to raise awareness on how to better handle the usage of JWT on mobile applications, in particular making sure we always do our best to avoid accidental logouts to provide a better user experience.

          A Smart Feature Flagging System for iOS

          • iOS
          • feature flags
          • Optimizely
          • Just Eat

          At Just Eat we have experimentation and feature flagging at our heart and we've developed a component, named JustTweak, to make things easier on iOS.

          How the iOS team at Just Eat built a scalable open-source solution to handle local and remote flags. Originally published on the Just Eat Engineering Blog. Overview At Just Eat we have experimentation at our heart, and it is very much dependent on feature flagging/toggling. If we may be so bold, here's an analogy: feature flagging is to experimentation as machine learning is to AI, you cannot have the second without the first one. We've developed an in-house component, named JustTweak, to handle feature flags and experiments on iOS without the hassle. We open-sourced JustTweak on github.com in 2017 and we have been evolving it ever since; in particular, with support for major experimentation platforms such as Optimizely and Firebase Remote Config. JustTweak has been instrumental in evolving the consumer Just Eat app in a fast and controlled manner, as well as to support a large number of integrations and migrations happening under the hood. In this article, we describe the feature flagging architecture and engine, with code samples and integration suggestions. What is feature flagging Feature flagging, in its original form, is a software development technique that provides an alternative to maintaining multiple source-code branches, so that a feature can be tested even before it is completed and ready for release. Feature flags are used in code to show/hide or enable/disable specific features at runtime. The technique also allows developers to release a version of a product that has unfinished features, that can be hidden from the user. Feature toggles also allow shorter software integration cycles and small incremental versions of software to be delivered without the cost of constant branching and merging - needless to say, this is crucial to have on iOS due to the App Store review process not allowing continuous delivery. A boolean flag in code is used to drive what code branch will run, but the concept can easily be extended to non-boolean flags, making them more of configuration flags that drive behavior. As an example, at Just Eat we have been gradually rewriting the whole application over time, swapping and customizing entire modules via configuration flags, allowing gradual switches from old to new features in a way transparent to the user. Throughout this article, the term 'tweaks' is used to refer to feature/configuration flags. A tweak can have a value of different raw types, namely Bool, String, Int, Float, and Double. Boolean tweaks can be used to drive features, like so: let isFeatureXEnabled: Bool = ... if isFeatureXEnabled { // show feature X } else { // don't show feature X } Other types of tweaks are instead useful to customise a given feature. Here is an example of configuring the environment using tweaks: let publicApiHost: String = ... let publicApiPort: Int? = ... let endpoint = Endpoint(scheme: "https", host: publicApiHost, port: publicApiPort, path: "/restaurant/:id/menu") // perform a request using the above endpoint object Problem The crucial part to get right is how and from where the flag values (isFeatureXEnabled, publicApiHost, and publicApiPort in the examples above) are fetched. Every major feature flagging/experimentation platform in the market provides its own way to fetch the values, and sometimes the APIs to do so significantly differ (e.g. Firebase Remote Config Vs Optimizely). Aware of the fact that it’s increasingly difficult to build any kind of non-trivial app without leveraging external dependencies, it's important to bear in mind that external dependencies pose a great threat to the long term stability and viability of any application. Following are some issues related to third-party experimentation solutions: third-party SDKs are not under your control using third-party SDKs in a modular architected app would easily cause dependency hell third-party SDKs are easily abused and various areas of your code will become entangled with them your company might decide to move to a different solution in the future and such switch comes with costs depending on the adopted solution, you might end up tying your app more and more to the platform-specific features that don't find correspondence elsewhere it is very hard to support multiple feature flag providers For the above reasons, it is best to hide third-party SDKs behind some sort of a layer and to implement an orchestration mechanism to allow fetching of flag values from different providers. We'll describe how we've achieved this in JustTweak. A note on the approach When designing software solutions, a clear trait was identified over time in the iOS team, which boils down to the kind of mindset and principle been used: Always strive to find solutions to problems that are scalable and hide complexity as much as possible. One word you would often hear if you were to work in the iOS team is 'Facade', which is a design pattern that serves as a front-facing interface masking more complex underlying or structural code. Facades are all over the place in our code: we try to keep components' interfaces as simple as possible so that other engineers could utilize them with minimal effort without necessarily knowing the implementation details. Furthermore, the more succinct an interface is, the rarer the possibility of misusages would be. We have some open source components embracing this approach, such as JustPersist, JustLog, and JustTrack. JustTweak makes no exception and the code to integrate it successfully in a project is minimal. Sticking to the above principle, the idea behind JustTweak is to have a single entry point to gather flag values, hiding the implementation details regarding which source the flag values are gathered from. JustTweak to the rescue JustTweak provides a simple facade interface interacting with multiple configurations that are queried respecting a certain priority. Configurations wrap specific sources of tweaks, that are then used to drive decisions or configurations in the client code. You can find JustTweak on CocoaPods and it's on version 5.0.0 at the time of writing. We plan to add support for Carthage and Swift Package Manager in the future. A demo app is also available for you to try it out. With JustTweak you can achieve the following: use a JSON local configuration providing default tweak values use a number of remote configuration providers, such as Firebase and Optmizely, to run A/B tests and feature flagging enable, disable, and customize features locally at runtime provide a dedicated UI for customization (this comes particularly handy for features that are under development to showcase the progress to stakeholders) Here is a screenshot of the TweakViewController taken from the demo app. Tweak values changed via this screen are immediately available to your code at runtime. Stack setup The facade class previously mentioned is represented by the TweakManager. There should only be a single instance of the manager, ideally configured at startup, passed around via dependency injection, and kept alive for the whole lifespan of the app. Following is an example of the kind of stack implemented as a static let. static let tweakManager: TweakManager = { // mutable configuration (to override tweaks from other configurations) let userDefaultsConfiguration = UserDefaultsConfiguration(userDefaults: .standard) // remote configurations (optional) let optimizelyConfiguration = OptimizelyConfiguration() let firebaseConfiguration = FirebaseConfiguration() // local JSON configuration (default tweaks) let jsonFileURL = Bundle.main.url(forResource: "Tweaks", withExtension: "json")! let localConfiguration = LocalConfiguration(jsonURL: jsonFileURL) // priority is defined by the order in the configurations array // (from highest to lowest) let configurations: [Configuration] = [userDefaultsConfiguration, optimizelyConfiguration, firebaseConfiguration, localConfiguration] return TweakManager(configurations: configurations) }() ``` JustTweak comes with three configurations out-of-the-box: UserDefaultsConfiguration which is mutable and uses UserDefaults as a key/value store LocalConfiguration which is read-only and uses a JSON configuration file that is meant to be the default configuration EphemeralConfiguration which is simply an instance of NSMutableDictionary Besides, JustTweak defines Configuration and MutableConfiguration protocols you can implement to create your own configurations to fit your needs. In the example project, you can find a few example configurations which you can use as a starting point. You can have any source of flags via wrapping it in a concrete implementation of the above protocols. Since the protocol methods are synchronous, you'll have to make sure that the underlying source has been initialised as soon as possible at startup. All the experimentation platforms provide mechanisms to do so, for example here is how Optimizely does it. The order of the objects in the configurations array defines the configurations' priority. The MutableConfiguration with the highest priority, such as UserDefaultsConfiguration in the example above, will be used to reflect the changes made in the UI (TweakViewController). The LocalConfiguration should have the lowest priority as it provides the default values from a local JSON file. It's also the one used by the TweakViewController to populate the UI. When fetching a tweak, the engine will inspect the chain of configurations in order and pick the tweak from the first configuration having it. The following diagram outlines a possible setup where values present in Optimizely override others in the subsequent configurations. Eventually, if no override is found, the local configuration would return the default tweak baked in the app. Structuring the stack this way brings various advantages: the same engine is used to customise the app for development, production, and test runs consumers only interface with the facade and can ignore the implementation details new code put behind flags can be shipped with confidence since we rely on a tested engine ability to remotely override tweaks de facto allowing to greatly customise the app without the need for a new release TweakManager gets populated with the tweaks listed in the JSON file used as backing store of the LocalConfiguration instance. It is therefore important to list every supported tweak in there so that development builds of the app can allow tweaking the values. Here is an excerpt from the file used in the TweakViewController screenshot above. { "ui_customization": { "display_red_view": { "Title": "Display Red View", "Description": "shows a red view in the main view controller", "Group": "UI Customization", "Value": false }, ... "red_view_alpha_component": { "Title": "Red View Alpha Component", "Description": "defines the alpha level of the red view", "Group": "UI Customization", "Value": 1.0 }, "label_text": { "Title": "Label Text", "Description": "the title of the main label", "Group": "UI Customization", "Value": "Test value" } }, "general": { "greet_on_app_did_become_active": { "Title": "Greet on app launch", "Description": "shows an alert on applicationDidBecomeActive", "Group": "General", "Value": false }, ... } } Testing considerations We've seen that the described architecture allows customization via configurations. We've shown in the above diagram that JustTweak can come handy when used in conjunction with our AutomationTools framework too, which is open-source. An Ephemeral configuration would define the app environment at run-time greatly simplifying the implementation of UI tests, which is well-known to be a tedious activity. Usage The two main features of JustTweak can be accessed from the TweakManager. Checking if a feature is enabled // check for a feature to be enabled let isFeatureXEnabled = tweakManager.isFeatureEnabled("feature_X") if isFeatureXEnabled { // show feature X } else { // hide feature X } Getting and setting the value of a flag for a given feature/variable. JustTweak will return the value from the configuration with the highest priority that provides it, or nil if none of the configurations have that feature/variable. // check for a tweak value let tweak = tweakManager.tweakWith(feature: <#feature_key#>, variable: <#variable_key#>") if let tweak = tweak { // tweak was found in some configuration, use tweak.value } else { // tweak was not found in any configuration } The Configuration and MutableConfiguration protocols define the following methods: func tweakWith(feature: String, variable: String) -> Tweak? func set(_ value: TweakValue, feature: String, variable: String) func deleteValue(feature: String, variable: String) You might wonder why is there a distinction between feature and variable. The reason is that we want to support the Optimizely lingo for features and related variables and therefore the design of JustTweak has to necessarily reflect that. Other experimentation platforms (such as Firebase) have a single parameter key, but we had to harmonise for the most flexible platform we support. Property Wrappers With SE-0258, Swift 5.1 introduces Property Wrappers. If you haven't read about them, we suggest you watch the WWDC 2019 "Modern Swift API Design talk where Property Wrappers are explained starting at 23:11. In short, a property wrapper is a generic data structure that encapsulates read/write access to a property while adding some extra behavior to augment its semantics. Common examples are @AtomicWrite and @UserDefault but more creative usages are up for grabs and we couldn't help but think of how handy it would be to have property wrappers for feature flags, and so we implemented them. @TweakProperty and @OptionalTweakProperty are available to mark properties representing feature flags. Here are a couple of examples, making the code so much nicer than before. @TweakProperty(fallbackValue: <#default_value#>, feature: <#feature_key#>, variable: <#variable_key#>, tweakManager: tweakManager) var isFeatureXEnabled: Bool @TweakProperty(fallbackValue: <#default_value#>, feature: <#feature_key#>, variable: <#variable_key#>, tweakManager: tweakManager) var publicApiHost: String @OptionalTweakProperty(fallbackValue: <#default_value_or_nil#>, feature: <#feature_key#>, variable: <#variable_key#>, tweakManager: tweakManager) var publicApiPort: Int? Mind that by using these property wrappers, a static instance of TweakManager must be available. Update a configuration at runtime JustTweak comes with a ViewController that allows the user to edit the tweaks while running the app. That is achieved by using the MutableConfiguration with the highest priority from the configurations array. This is de facto a debug menu, useful for development and internal builds but not to include in release builds. #if DEBUG func presentTweakViewController() { let tweakViewController = TweakViewController(style: .grouped, tweakManager: tweakManager) // either present it modally or push it on a UINavigationController } #endif Additionally, when a value is modified in any MutableConfiguration, a notification is fired to give the clients the opportunity to react and reflect changes in the UI. override func viewDidLoad() { super.viewDidLoad() NotificationCenter.defaultCenter().addObserver(self, selector: #selector(updateUI), name: TweakConfigurationDidChangeNotification, object: nil) } @objc func updateUI() { // update the UI accordingly } A note on modular architecture It's reasonable to assume that any non-trivial application approaching 2020 is composed of a number of modules and our Just Eat iOS app surely is too. With more than 30 modules developed in-house, it's crucial to find a way to inject flags into the modules but also to avoid every module to depend on an external library such as JustTweak. One way to achieve this would be: define one or more protocols in the module with the set of properties desired structure the modules to allow dependency injection of objects conforming to the above protocol implement logic in the module to consume the injected objects For instance, you could have a class wrapping the manager like so: protocol ModuleASettings { var isFeatureXEnabled: Bool { get } } protocol ModuleBSettings { var publicApiHost: String { get } var publicApiPort: Int? { get } } import JustTweak public class AppConfiguration: ModuleASettings, ModuleBSettings { static let tweakManager: TweakManager = { ... } @TweakProperty(...) var isFeatureXEnabled: Bool @TweakProperty(...) var publicApiHost: String @OptionalTweakProperty(...) var publicApiPort: Int? } Future evolution With recent versions of Swift and especially with 5.1, developers have a large set of powerful new tools, such as generics, associated types, opaque types, type erasure, etc. With Combine and SwiftUI entering the scene, developers are also starting adopting new paradigms to write code. Sensible paths to evolve JustTweak could be to have the Tweak object be generic on TweakValue have TweakManager be an ObservableObject which will enable publishing of events via Combine, and use @EnvironmentObject to ease the dependency injection in the SwiftUI view hierarchy. While such changes will need time to be introduced since our contribution to JustTweak is in-line with the evolution of the Just Eat app (and therefore a gradual adoption of SwiftUI), we can't wait to see them implemented. If you desire to contribute, we are more than happy to receive pull requests. Conclusion In this article, we illustrated how JustTweak can be of great help in adding flexible support to feature flagging. Integrations with external providers/experimentation platforms such as Optimizely, allow remote override of flags without the need of building a new version of the app, while the UI provided by the framework allows local overrides in development builds. We've shown how to integrate JustTweak in a project, how to setup a reasonable stack with a number of configurations and we’ve given you some guidance on how to leverage it when writing UI tests. We believe JustTweak to be a great tool with no similar open source alternatives nor proprietary ones and we hope developers will adopt it more and more.

          Deep Linking at Scale on iOS

          • deep links
          • deep linking
          • universal links
          • iOS
          • navigation
          • flow controllers
          • state machine
          • futures
          • promises
          • Just Eat

          How the iOS team at Just Eat built a scalable architecture to support navigation and deep linking.

          Originally published on the Just Eat Engineering Blog.

          In this article, we propose an architecture to implement a scalable solution to Deep Linking on iOS using an underlying Flow Controller-based architecture, all powered

          How the iOS team at Just Eat built a scalable architecture to support navigation and deep linking. Originally published on the Just Eat Engineering Blog. In this article, we propose an architecture to implement a scalable solution to Deep Linking on iOS using an underlying Flow Controller-based architecture, all powered by a state machine and the Futures & Promises paradigm to keep the code more readable. At Just Eat, we use a dedicated component named NavigationEngine that is domain-specific to the Just Eat apps and their use cases. A demo project named NavigationEngineDemo that includes the NavigationEngine architecture (stripped out of many details not necessary to showcase the solution) is available on GitHub. Overview Deep linking is one of the most underestimated problems to solve on mobile. A naïve explanation would say that given some sort of input, mobile apps can load a specific screen, but it only has practical meaning when combined with Universal Links on iOS and App Links on Android. In such cases, the input is a URL that would load a web page on the companion website. Let's use an example from Just Eat: opening the URL https://www.just-eat.co.uk/area/ec4m-london on a web browser would load the list of restaurants in the UK London area for the postcode EC4M. Deep linking to the mobile apps using the same URL should give a similar experience to the user. In reality, the problem is more complex than what it seems at first glance; non-tech people - and sometimes even developers - find it hard to grasp. Loading a web page in a browser is fundamentally different from implementing dedicated logic on mobile to show a UIViewController (iOS) or Activity (Android) to the user and populate it with information that will most likely be gathered from an API call. The logic to perform deep linking starts with parsing the URL, understanding the intent, constructing the user journey, performing the navigation to the target screen passing the info all the way down, and ultimately loading any required data asynchronously from a remote API. On top of all this, it also has to consider the state of the app: the user might have previously left the app in a particular state and dedicated logic would be needed to deep link from the existing to the target screen. A scenario to consider is when the user is not logged in and therefore some sections of the app may not be available. Deep linking can actually be triggered from a variety of sources: Safari web browser any app that allows tapping on a link (iMessage, Notes, etc.) any app that explicitly tries to open the app using custom URL schemes the app itself (to perform jumps between sections) TodayExtension Shortcut items (Home Screen Quick Actions) Spotlight items It should be evident that implementing a comprehensive and scalable solution that fully addresses deep linking is far from being trivial. It shouldn't be an after-thought but rather be baked into the app architecture from the initial app design. It should also be quite glaring what the main problem that needs to be solved first is: the app Navigation. Navigation itself is not a problem with a single solution (if it was, the solution would be provided by Apple/Google and developers would simply stick to it). A number of solutions were proposed over the years trying to make it simpler and generic to some degree - Router, Compass, XCoordinator to name just a few open-source components. I proposed the concept of Flow Controllers in my article Flow Controllers on iOS for a better navigation control back in 2014 when the community had already (I believe) started shifting towards similar approaches. Articles such as Improve your iOS Architecture with FlowControllers (by Krzysztof Zabłocki), A Better MVC, Part 2: Fixing Encapsulation (by Dave DeLong), Flow Coordinators in iOS (by Dennis Walsh), and even as recently as 2019, Navigation with Flow Controllers (by Majid Jabrayilov) was published. To me, all the proposals share one main common denominator: flow controllers/coordinator and their API are necessarily domain-specific. Consider the following methods taken from one of the articles mentioned above referring to specific use cases: func showLoginViewController() { ... } func showSignupViewController() { ... } func showPasswordViewController() { ... } With the support of colleagues and friends, I tried proposing a generic and abstract solution but ultimately hit a wall. Attempts were proposed using enums to list the supported transitions (as XCoordinator shows in its README for instance) or relying on meta-programming dark magic in Objective-C (which is definitely the sign of a terrible design), neither of which satisfied me in terms of reusability and abstraction. I ultimately realized that it's perfectly normal for such problem to be domain-specific and that we don't necessarily have to find abstract solutions to all problems. Terminology For clarity on some of the terminology used in this article. Deep Linking: the ability to reach specific screens (via a flow) in the app either via a Deep Link or a Universal Link. Deep Link: URI with custom scheme (e.g. just-eat://just-eat.co.uk/login, just-eat-dk://just-eat.co.uk/settings) containing the information to perform deep linking in the app. When it comes to deep links, the host is irrelevant but it's good to keep it as part of the URL since it makes it easier to construct the URL using URLComponents and it keeps things more 'standard'. Universal Link: URI with http/https scheme (e.g. https://just-eat.co.uk/login) containing the information to perform deep linking in the app. Intent: the abstract intent of reaching a specific area of the app. E.g. goToOrderDetails(OrderId). State machine transition: transitions in the state machine allow navigating to a specific area in the app (state) from another one. If the app is in a state where the deep linking to a specific screen should not be allowed, the underlying state machine should not have the corresponding transition. Solution NavigationEngine is the iOS module (pod) used by the teams at Just Eat, that holds the isolated logic for navigation and deep linking. As mentioned above, the magic sauce includes the usage of: FlowControllers to handle the transitions between ViewControllers in a clear and pre-defined way. Stateful state machines to allow transitions according to the current application state. More information on FSM (Finite State Machine) here and on the library at The easiest State Machine in Swift. Promis to keep the code readable using Futures & Promises to help avoiding the Pyramid of doom. Sticking to such a paradigm is also a key aspect for the whole design since every API in the stack is async. More info on the library at The easiest Promises in Swift. a pretty heavy amount of 🧠 NavigationEngine maintains separation of concerns between URL Parsing, Navigation, and Deep Linking. Readers can inspect the code in the NavigationEngineDemo project that also includes unit tests with virtually 100% code coverage. Following is an overview of the class diagram of the entire architecture stack. Architecture class diagram While the navigation is powered by a FlowController-based architecture, the deep linking logic is powered by NavigationIntentHandler and NavigationTransitioner (on top of the navigation stack). Note the single entry point named DeepLinkingFacade exposes the following API to cover the various input/sources we mentioned earlier: public func handleURL(_ url: URL) -> Future<Bool> public func openDeepLink(_ deepLink: DeepLink) -> Future<Bool> public func openShortcutItem(_ item: UIApplicationShortcutItem) -> Future<Bool> public func openSpotlightItem(_ userActivity: NSUserActivityProtocol) -> Future<Bool> Here are the sequence diagrams for each one. Refer to the demo project to inspect the code. Navigation As mentioned earlier, the important concept to grasp is that there is simply no single solution to Navigation. I've noticed that such a topic quickly raises discussions and each engineer has different, sometimes strong opinions. It's more important to agree on a working solution that satisfies the given requirements rather than forcing personal preferences. Our NavigationEngine relies on the following navigation rules (based on Flow Controllers): FlowControllers wire up the domain-specific logic for the navigation ViewControllers don't allocate FlowControllers Only FlowControllers, AppDelegate and similar top-level objects can allocate ViewControllers FlowControllers are owned (retained) by the creators FlowControllers can have children FlowControllers and create a parent-child chain and can, therefore, be in a 1-to-many relationship FlowControllers in parent-child relationships communicate via delegation ViewControllers have weak references to FlowControllers ViewControllers are in a 1-to-1 relationship with FlowControllers All the FlowController domain-specific API must be future-based with Future<Bool> as return type Deep linking navigation should occur with no more than one animation (i.e. for long journeys, only the last step should be animated) Deep linking navigation that pops a stack should occur without animation In the demo project, there are a number of *FlowControllerProtocols, each corresponding to a different section/domain of the hosting app. Examples such as RestaurantsFlowControllerProtocol and OrdersFlowControllerProtocol are taken from the Just Eat app and each one has domain specific APIs, e.g: func goToSearchAnimated(postcode: Postcode?, cuisine: Cuisine?, animated: Bool) -> Future<Bool> func goToOrder(orderId: OrderId, animated: Bool) -> Future<Bool> func goToRestaurant(restaurantId: RestaurantId) -> Future<Bool> func goToCheckout(animated: Bool) -> Future<Bool> Note that each one: accepts the animated parameter returns Future<Bool> so that flow sequence can be combined Flow controllers should be combined sensibly to represent the app UI structure. In the case of Just Eat we have a RootFlowController as the root-level flow controller orchestrating the children. A FlowControllerProvider, used by the NavigationTransitioner, is instead the single entry point to access the entire tree of flow controllers. NavigationTransitioner provides an API such as: func goToLogin(animated: Bool) -> Future<Bool> func goFromHomeToSearch(postcode: Postcode?, cuisine: Cuisine?, animated: Bool) -> Future<Bool> This is responsible to keep the underlying state machine and what the app actually shows in sync. Note the goFromHomeToSearch method being verbose on purpose; it takes care of the specific transition from a given state (home). One level up in the stack, NavigationIntentHandler is responsible for combining the actions available from the NavigationTransitioner starting from a given NavigationIntent and creating a complete deep linking journey. It also takes into account the current state of the app. For example, showing the history of the orders should be allowed only if the user is logged in, but it would also be advisable to prompt the user to log in in case he/she is not, and then resume the original action. Allowing so provides a superior user experience rather than simply aborting the flow (it's what websites achieve by using the referring URL). Here is the implementation of the .goToOrderHistory intent in the NavigationIntentHandler: case .goToOrderHistory: switch userStatusProvider.userStatus { case .loggedIn: return navigationTransitioner.goToRoot(animated: false).thenWithResult { _ -> Future<Bool> in self.navigationTransitioner.goToOrderHistory(animated: true) } case .loggedOut: return navigationTransitioner.requestUserToLogin().then { future in switch future.state { case .result: return self.handleIntent(intent) // go recursive default: return Future<Bool>.futureWithResolution(of: future) } } } Since in the design we make the entire API future-based, we can potentially interrupt the deep linking flow to prompt the user for details or simply gather missing information from a remote API. This is crucial and allows us to construct complex flows. By design, all journeys start by resetting the state of the app by calling goToRoot. This vastly reduces the number of possible transitions to take care of as we will describe in more detail in the next section dedicated to the underlying state machine. State Machine As you might have realized by now, the proposed architecture makes use of an underlying Finite State Machine to keep track of the state of the app during a deep linking journey. Here is a simplified version of the state machine configurations used in the Just Eat iOS apps. In the picture, the red arrows are transitions that are available for logged in users only, the blue ones are for logged out users only, while the black ones can always be performed. Note that every state should allow going back to the .allPoppedToRoot state so that, regardless of what the current state of the app is, we can always reset the state and perform a deep linking action starting afresh. This drastically simplifies the graph, avoiding unnecessary transitions such as the one shown in the next picture. Notice that intents (NavigationIntent) are different from transitions (NavigationEngine.StateMachine.EventType). An intent contains the information to perform a deep linking journey, while the event type is the transition from one FSM state to another (or the same). NavigationTransitioner is the class that performs the transitions and applies the companion navigation changes. A navigation step is performed only if the corresponding transition is allowed and completed successfully. If a transition is not allowed, the flow is interrupted, reporting an error in the future. You can showcase a failure in the demo app by trying to follow the Login Universal Link (https://just-eat.co.uk/login) after having faked the login when following the Order History Universal Link (https://just-eat.co.uk/orders). Usage NavigationEngineDemo includes the whole stack that readers can use in client projects. Here are the steps for a generic integration of the code. Add the NavigationEngine stack (NavigationEngineDemo/NavigationEngine folder) to the client project. This can be done by either creating a dedicated pod as we do at Just Eat or by directly including the code. Include Promis and Stateful as dependencies in your Podfile (assuming the usage of Cocoapods). Modify according to your needs, implement classes for all the *FlowControllerProtocols, and connect them to the ViewControllers of the client. This step can be quite tedious depending on the status of your app and we suggest trying to mimic what has been done in the demo app. Add CFBundleTypeRole and CFBundleURLSchemes to the main target Info.plist file to support Deep Links. E.g. <key>CFBundleURLTypes</key> <array> <dict> <key>CFBundleTypeRole</key> <string>Editor</string> <key>CFBundleURLSchemes</key> <array> <string>je-internal</string> <string>justeat</string> <string>just-eat</string> <string>just-eat-uk</string> </array> </dict> </array> Add the applinks (in the Capabilities -> Associated Domains section of the main target) you'd like to support. This will allow iOS to register the app for Universal Links on the given domains looking for the apple-app-site-association file at the root of those domains once the app is installed. E.g. Implement concrete classes for DeepLinkingSettingsProtocol and UserStatusProviding according to your needs. Again, see the examples in the demo project. The internalDeepLinkSchemes property in DeepLinkSettingsProtocol should contain the same values previously added to CFBundleURLSchemes, while the universalLinkHosts should contain the same applinks: values defined in Capabilities -> Associated Domains. Setup the NavigationEngine stack in the AppDelegate's applicationDidFinishLaunching. To some degree, it should be something similar to the following: var window: UIWindow? var rootFlowController: RootFlowController! var deepLinkingFacade: DeepLinkingFacade! var userStatusProvider = UserStatusProvider() let deepLinkingSettings = DeepLinkingSettings() func applicationDidFinishLaunching(_ application: UIApplication) { // Init UI Stack let window = UIWindow(frame: UIScreen.main.bounds) let tabBarController = TabBarController.instantiate() // Root Flow Controller rootFlowController = RootFlowController(with: tabBarController) tabBarController.flowController = rootFlowController // Deep Linking core let flowControllerProvider = FlowControllerProvider(rootFlowController: rootFlowController) deepLinkingFacade = DeepLinkingFacade(flowControllerProvider: flowControllerProvider, navigationTransitionerDataSource: self, settings: deepLinkingSettings, userStatusProvider: userStatusProvider) // Complete UI Stack window.rootViewController = tabBarController window.makeKeyAndVisible() self.window = window } Modify NavigationTransitionerDataSource according to your needs and implement its methods. You might want to have a separate component and not using the AppDelegate. extension AppDelegate: NavigationTransitionerDataSource { func navigationTransitionerDidRequestUserToLogin() -> Future<Bool> { <#async logic#> } ... } Implement the entry points for handling incoming URLs/inputs in the AppDelegate: func application(_ app: UIApplication, open url: URL, options: [UIApplication.OpenURLOptionsKey : Any] = [:]) -> Bool { // from internal deep links & TodayExtension deepLinkingFacade.openDeeplink(url).finally { future in <#...#> } return true } func application(_ application: UIApplication, continue userActivity: NSUserActivity, restorationHandler: @escaping ([UIUserActivityRestoring]?) -> Void) -> Bool { switch userActivity.activityType { // from Safari case NSUserActivityTypeBrowsingWeb: if let webpageURL = userActivity.webpageURL { self.deepLinkingFacade.handleURL(webpageURL).finally { future in <#...#> } return true } return false // from Spotlight case CSSearchableItemActionType: self.deepLinkingFacade.openSpotlightItem(userActivity).finally { future in let originalInput = userActivity.userInfo![CSSearchableItemActivityIdentifier] as! String <#...#> } return true default: return false } } func application(_ application: UIApplication, performActionFor shortcutItem: UIApplicationShortcutItem, completionHandler: @escaping (Bool) -> Void) { // from shortcut items (Home Screen Quick Actions) deepLinkingFacade.openShortcutItem(shortcutItem).finally { future in let originalInput = shortcutItem.type <#...#> completionHandler(future.hasResult()) } } N.B. Since a number of tasks are usually performed at startup (both from cold and warm starts), it's suggested to schedule them using operation queues. The deep linking task should be one of the last tasks in the queue to make sure that dependencies are previously set up. Here is the great Advanced NSOperations talk by Dave DeLong from WWDC15. The UniversalLinkConverter class should be modified to match the paths in the apple-app-site-association, which should be reachable at the root of the website (the associated domain). It should be noted that if the app is opened instead of the browser, it would be because the Universal Link can be handled; and redirecting the user back to the web would be a fundamental mistake that should be solved by correctly defining the supported paths in the apple-app-site-association file. To perform internal app navigation via deep linking, the DeeplinkFactory class should be used to create DeepLink objects that can be fed into either handleURL(_ url: URL) or openDeepLink(_ deepLink: DeepLink). In-app testing The module exposes a DeepLinkingTesterViewController that can be used to easily test deep linking within an app. Simply define a JSON file containing the Universal Links and Deep Links to test: { "universal_links": [ "https://just-eat.co.uk/", "https://just-eat.co.uk/home", "https://just-eat.co.uk/login", ... ], "deep_links": [ "JUSTEAT://irrelev.ant/home", "justeat://irrelev.ant/login", "just-eat://irrelev.ant/resetPassword?resetToken=xyz", ... ] } Then feed it to the view controller as shown below. Alternatively, use a storyboard reference as shown in the demo app. let deepLinkingTesterViewController = DeepLinkingTesterViewController.instantiate() deepLinkingTesterViewController.delegate = self let path = Bundle.main.path(forResource: "deeplinking_test_list", ofType: "json")! deepLinkingTesterViewController.loadTestLinks(atPath: path) and implement the DeepLinkingTesterViewControllerDelegate extension AppDelegate: DeepLinkingTesterViewControllerDelegate { func deepLinkingTesterViewController(_ deepLinkingTesterViewController: DeepLinkingTesterViewController, didSelect url: URL) { self.deepLinkingFacade.handleURL(universalLink).finally { future in self.handleFuture(future, originalInput: universalLink.absoluteString) } } } Conclusion The solution proposed in this article has proven to be highly scalable and customizable. We shipped it in the Just Eat iOS apps in March 2019 and our teams are gradually increasing the number of Universal Links supported as you can see from our apple-app-site-association. Before implementing and adopting NavigationEngine, supporting new kinds of links was a real hassle. Thanks to this architecture, it is now easy for each team in the company to support new deep link journeys. The declarative approach in defining the API, states, transitions, and intents forces a single way to extend the code which enables a coherent approach throughout the codebase.

          Principal Manifesto

          • manifesto
          • tech
          • roles
          • principal
          • staff
          • engineering

          Edit: in 2020, Will Larson published Staff Engineer, the first book that properly reasons about Staff+ roles. I cannot recommend the book, the articles, and the podcast enough. You can find all about them at staffeng.com.

          To extend the tech career ladder, a number of roles have been introduced

          Edit: in 2020, Will Larson published Staff Engineer, the first book that properly reasons about Staff+ roles. I cannot recommend the book, the articles, and the podcast enough. You can find all about them at staffeng.com. To extend the tech career ladder, a number of roles have been introduced in the tech community over the past years. Depending on the company and related role and level fragmentation, they might go by different labels such as "Principal Engineer", "VP Engineer", "Distinguished Engineer", "Staff Engineer", "Fellow", "Architect" or sometimes, in small environments, simply "Tech Lead". Such roles are intended to allow progression and recognition for the company's most senior staff giving individuals the ability to grow above a senior level which is becoming more and more mainstream these days and while whose responsibilities may vary, it is too often labeled as expert programmer with a solid tech background and decent experience on the CV. Senior engineers might progress their career towards a managerial path (people management) or prefer to stay focused on the tech side of things (the above roles). I have seen people being very good in the roles mentioned above as natural technical leaders: such individuals were great engineers on their own, well respected by the engineers around them, worked well within teams, understood how software should be designed, built and shipped, and often had a decent sense for making the right kinds of product tradeoffs. Such engineers were willing to do enough project management and people development to keep the team/project humming along. Engineers in these roles usually remain pretty connected with the details of the project and successfully manage/influence from within rather than from outside the project. As a Principal Engineer, I sometimes found describing my role and my responsibilities being too vague at times, with tasks dipping into various topics, especially depending on the need of the company at a particular point in time. For such reason, I list here the expectations and responsibilities of the Principal role in the way I've experienced it in my career so far. The document, therefore, represents the Principal Manifesto I stand by. Principal Engineers should be expected to: Define tech vision 1-2 years ahead, plan accordingly with the teams and promote it across the business. Define and gradually execute a tech roadmap that aligns with the business requirements and demands and have Tech/Delivery/Product managers supporting it. Persuade teams to do the right thing and align on processes whenever possible. Work with them whenever necessary in a collaborative way and with an eye on the status of the progress across the team. Be able to manage expectations with stakeholders and not over-promise. Help to establish a consensus between the engineering group on architecture, patterns and practices. Understand how software should be designed at both high and low-level, built and shipped, considering maintainability and costs. Understand the company tech platform as a whole. Introduce evolutive, safe, and sound changes both from a technical point of view and a tooling & standards point of view. Collaborate across teams when necessary to move projects forward and smooth the edges when a project is dragging. Identify small course corrections to avoid long term debt or failing projects. Call out good work and highlight poor work to line managers. Be identified as professionals ‘to go to’ and be a respected authority on specific projects/areas/technologies by other engineers but also by management. Being trusted in deciding on what to work on and what projects demands dedicated attention. Be able to solve complex problems both small and large and manage projects of all sizes in isolation and in a team. Be able to make sensible and rational decisions (both technical and not). Successfully own investigations of issues impacting the platform and discuss with the relevant teams to aim for a resolution. Coach, inspire and share knowledge with other engineers. Be great at leading by example by being a top contributor to the platform delivering top standards of quality at all stages of the software development life cycle. Promote the company externally cultivating white papers, blogs posts, and public talks. Be a respected authority in the community: open-source contributor, writing blogs posts, books and other material, public talks. Have a proven and recognized history of success. Similar articles: On being a Principal Engineer What does a Principal Developer do

          Articles for people who make web sites.

          User Research Is Storytelling

            Ever since I was a boy, I’ve been fascinated with movies. I loved the characters and the excitement—but most of all the stories. I wanted to be an actor. And I believed that I’d get to do the things that Indiana Jones did and go on exciting adventures. I even dreamed up ideas for movies that my friends and I could make and star in. But they never went any further. I did, however, end up working in user experience (UX). Now, I realize that there’s an element of theater to UX—I hadn’t really considered it before, but user research is storytelling. And to get the most out of user research, you need to tell a good story where you bring stakeholders—the product team and decision makers—along and get them interested in learning more.

            Think of your favorite movie. More than likely it follows a three-act structure that’s commonly seen in storytelling: the setup, the conflict, and the resolution. The first act shows what exists today, and it helps you get to know the characters and the challenges and problems that they face. Act two introduces the conflict, where the action is. Here, problems grow or get worse. And the third and final act is the resolution. This is where the issues are resolved and the characters learn and change. I believe that this structure is also a great way to think about user research, and I think that it can be especially helpful in explaining user research to others.

            Three-act structure in movies (© 2024 StudioBinder. Image used with permission from StudioBinder.). Use storytelling as a structure to do research

            It’s sad to say, but many have come to see research as being expendable. If budgets or timelines are tight, research tends to be one of the first things to go. Instead of investing in research, some product managers rely on designers or—worse—their own opinion to make the “right” choices for users based on their experience or accepted best practices. That may get teams some of the way, but that approach can so easily miss out on solving users’ real problems. To remain user-centered, this is something we should avoid. User research elevates design. It keeps it on track, pointing to problems and opportunities. Being aware of the issues with your product and reacting to them can help you stay ahead of your competitors.

            In the three-act structure, each act corresponds to a part of the process, and each part is critical to telling the whole story. Let’s look at the different acts and how they align with user research.

            Act one: setup

            The setup is all about understanding the background, and that’s where foundational research comes in. Foundational research (also called generative, discovery, or initial research) helps you understand users and identify their problems. You’re learning about what exists today, the challenges users have, and how the challenges affect them—just like in the movies. To do foundational research, you can conduct contextual inquiries or diary studies (or both!), which can help you start to identify problems as well as opportunities. It doesn’t need to be a huge investment in time or money.

            Erika Hall writes about minimum viable ethnography, which can be as simple as spending 15 minutes with a user and asking them one thing: “‘Walk me through your day yesterday.’ That’s it. Present that one request. Shut up and listen to them for 15 minutes. Do your damndest to keep yourself and your interests out of it. Bam, you’re doing ethnography.” According to Hall, [This] will probably prove quite illuminating. In the highly unlikely case that you didn’t learn anything new or useful, carry on with enhanced confidence in your direction.”  

            This makes total sense to me. And I love that this makes user research so accessible. You don’t need to prepare a lot of documentation; you can just recruit participants and do it! This can yield a wealth of information about your users, and it’ll help you better understand them and what’s going on in their lives. That’s really what act one is all about: understanding where users are coming from. 

            Jared Spool talks about the importance of foundational research and how it should form the bulk of your research. If you can draw from any additional user data that you can get your hands on, such as surveys or analytics, that can supplement what you’ve heard in the foundational studies or even point to areas that need further investigation. Together, all this data paints a clearer picture of the state of things and all its shortcomings. And that’s the beginning of a compelling story. It’s the point in the plot where you realize that the main characters—or the users in this case—are facing challenges that they need to overcome. Like in the movies, this is where you start to build empathy for the characters and root for them to succeed. And hopefully stakeholders are now doing the same. Their sympathy may be with their business, which could be losing money because users can’t complete certain tasks. Or maybe they do empathize with users’ struggles. Either way, act one is your initial hook to get the stakeholders interested and invested.

            Once stakeholders begin to understand the value of foundational research, that can open doors to more opportunities that involve users in the decision-making process. And that can guide product teams toward being more user-centered. This benefits everyone—users, the product, and stakeholders. It’s like winning an Oscar in movie terms—it often leads to your product being well received and successful. And this can be an incentive for stakeholders to repeat this process with other products. Storytelling is the key to this process, and knowing how to tell a good story is the only way to get stakeholders to really care about doing more research. 

            This brings us to act two, where you iteratively evaluate a design or concept to see whether it addresses the issues.

            Act two: conflict

            Act two is all about digging deeper into the problems that you identified in act one. This usually involves directional research, such as usability tests, where you assess a potential solution (such as a design) to see whether it addresses the issues that you found. The issues could include unmet needs or problems with a flow or process that’s tripping users up. Like act two in a movie, more issues will crop up along the way. It’s here that you learn more about the characters as they grow and develop through this act. 

            Usability tests should typically include around five participants according to Jakob Nielsen, who found that that number of users can usually identify most of the problems: “As you add more and more users, you learn less and less because you will keep seeing the same things again and again… After the fifth user, you are wasting your time by observing the same findings repeatedly but not learning much new.” 

            There are parallels with storytelling here too; if you try to tell a story with too many characters, the plot may get lost. Having fewer participants means that each user’s struggles will be more memorable and easier to relay to other stakeholders when talking about the research. This can help convey the issues that need to be addressed while also highlighting the value of doing the research in the first place.

            Researchers have run usability tests in person for decades, but you can also conduct usability tests remotely using tools like Microsoft Teams, Zoom, or other teleconferencing software. This approach has become increasingly popular since the beginning of the pandemic, and it works well. You can think of in-person usability tests like going to a play and remote sessions as more like watching a movie. There are advantages and disadvantages to each. In-person usability research is a much richer experience. Stakeholders can experience the sessions with other stakeholders. You also get real-time reactions—including surprise, agreement, disagreement, and discussions about what they’re seeing. Much like going to a play, where audiences get to take in the stage, the costumes, the lighting, and the actors’ interactions, in-person research lets you see users up close, including their body language, how they interact with the moderator, and how the scene is set up.

            If in-person usability testing is like watching a play—staged and controlled—then conducting usability testing in the field is like immersive theater where any two sessions might be very different from one another. You can take usability testing into the field by creating a replica of the space where users interact with the product and then conduct your research there. Or you can go out to meet users at their location to do your research. With either option, you get to see how things work in context, things come up that wouldn’t have in a lab environment—and conversion can shift in entirely different directions. As researchers, you have less control over how these sessions go, but this can sometimes help you understand users even better. Meeting users where they are can provide clues to the external forces that could be affecting how they use your product. In-person usability tests provide another level of detail that’s often missing from remote usability tests. 

            That’s not to say that the “movies”—remote sessions—aren’t a good option. Remote sessions can reach a wider audience. They allow a lot more stakeholders to be involved in the research and to see what’s going on. And they open the doors to a much wider geographical pool of users. But with any remote session there is the potential of time wasted if participants can’t log in or get their microphone working. 

            The benefit of usability testing, whether remote or in person, is that you get to see real users interact with the designs in real time, and you can ask them questions to understand their thought processes and grasp of the solution. This can help you not only identify problems but also glean why they’re problems in the first place. Furthermore, you can test hypotheses and gauge whether your thinking is correct. By the end of the sessions, you’ll have a much clearer picture of how usable the designs are and whether they work for their intended purposes. Act two is the heart of the story—where the excitement is—but there can be surprises too. This is equally true of usability tests. Often, participants will say unexpected things, which change the way that you look at things—and these twists in the story can move things in new directions. 

            Unfortunately, user research is sometimes seen as expendable. And too often usability testing is the only research process that some stakeholders think that they ever need. In fact, if the designs that you’re evaluating in the usability test aren’t grounded in a solid understanding of your users (foundational research), there’s not much to be gained by doing usability testing in the first place. That’s because you’re narrowing the focus of what you’re getting feedback on, without understanding the users' needs. As a result, there’s no way of knowing whether the designs might solve a problem that users have. It’s only feedback on a particular design in the context of a usability test.  

            On the other hand, if you only do foundational research, while you might have set out to solve the right problem, you won’t know whether the thing that you’re building will actually solve that. This illustrates the importance of doing both foundational and directional research. 

            In act two, stakeholders will—hopefully—get to watch the story unfold in the user sessions, which creates the conflict and tension in the current design by surfacing their highs and lows. And in turn, this can help motivate stakeholders to address the issues that come up.

            Act three: resolution

            While the first two acts are about understanding the background and the tensions that can propel stakeholders into action, the third part is about resolving the problems from the first two acts. While it’s important to have an audience for the first two acts, it’s crucial that they stick around for the final act. That means the whole product team, including developers, UX practitioners, business analysts, delivery managers, product managers, and any other stakeholders that have a say in the next steps. It allows the whole team to hear users’ feedback together, ask questions, and discuss what’s possible within the project’s constraints. And it lets the UX research and design teams clarify, suggest alternatives, or give more context behind their decisions. So you can get everyone on the same page and get agreement on the way forward.

            This act is mostly told in voiceover with some audience participation. The researcher is the narrator, who paints a picture of the issues and what the future of the product could look like given the things that the team has learned. They give the stakeholders their recommendations and their guidance on creating this vision.

            Nancy Duarte in the Harvard Business Review offers an approach to structuring presentations that follow a persuasive story. “The most effective presenters use the same techniques as great storytellers: By reminding people of the status quo and then revealing the path to a better way, they set up a conflict that needs to be resolved,” writes Duarte. “That tension helps them persuade the audience to adopt a new mindset or behave differently.”

            A persuasive story pattern.

            This type of structure aligns well with research results, and particularly results from usability tests. It provides evidence for “what is”—the problems that you’ve identified. And “what could be”—your recommendations on how to address them. And so on and so forth.

            You can reinforce your recommendations with examples of things that competitors are doing that could address these issues or with examples where competitors are gaining an edge. Or they can be visual, like quick mockups of how a new design could look that solves a problem. These can help generate conversation and momentum. And this continues until the end of the session when you’ve wrapped everything up in the conclusion by summarizing the main issues and suggesting a way forward. This is the part where you reiterate the main themes or problems and what they mean for the product—the denouement of the story. This stage gives stakeholders the next steps and hopefully the momentum to take those steps!

            While we are nearly at the end of this story, let’s reflect on the idea that user research is storytelling. All the elements of a good story are there in the three-act structure of user research: 

            • Act one: You meet the protagonists (the users) and the antagonists (the problems affecting users). This is the beginning of the plot. In act one, researchers might use methods including contextual inquiry, ethnography, diary studies, surveys, and analytics. The output of these methods can include personas, empathy maps, user journeys, and analytics dashboards.
            • Act two: Next, there’s character development. There’s conflict and tension as the protagonists encounter problems and challenges, which they must overcome. In act two, researchers might use methods including usability testing, competitive benchmarking, and heuristics evaluation. The output of these can include usability findings reports, UX strategy documents, usability guidelines, and best practices.
            • Act three: The protagonists triumph and you see what a better future looks like. In act three, researchers may use methods including presentation decks, storytelling, and digital media. The output of these can be: presentation decks, video clips, audio clips, and pictures. 

            The researcher has multiple roles: they’re the storyteller, the director, and the producer. The participants have a small role, but they are significant characters (in the research). And the stakeholders are the audience. But the most important thing is to get the story right and to use storytelling to tell users’ stories through research. By the end, the stakeholders should walk away with a purpose and an eagerness to resolve the product’s ills. 

            So the next time that you’re planning research with clients or you’re speaking to stakeholders about research that you’ve done, think about how you can weave in some storytelling. Ultimately, user research is a win-win for everyone, and you just need to get stakeholders interested in how the story ends.

            To Ignite a Personalization Practice, Run this Prepersonalization Workshop

              Picture this. You’ve joined a squad at your company that’s designing new product features with an emphasis on automation or AI. Or your company has just implemented a personalization engine. Either way, you’re designing with data. Now what? When it comes to designing for personalization, there are many cautionary tales, no overnight successes, and few guides for the perplexed. 

              Between the fantasy of getting it right and the fear of it going wrong—like when we encounter “persofails” in the vein of a company repeatedly imploring everyday consumers to buy additional toilet seats—the personalization gap is real. It’s an especially confounding place to be a digital professional without a map, a compass, or a plan.

              For those of you venturing into personalization, there’s no Lonely Planet and few tour guides because effective personalization is so specific to each organization’s talent, technology, and market position. 

              But you can ensure that your team has packed its bags sensibly.

              Designing for personalization makes for strange bedfellows. A savvy art-installation satire on the challenges of humane design in the era of the algorithm. Credit: Signs of the Times, Scott Kelly and Ben Polkinghome.

              There’s a DIY formula to increase your chances for success. At minimum, you’ll defuse your boss’s irrational exuberance. Before the party you’ll need to effectively prepare.

              We call it prepersonalization.

              Behind the music

              Consider Spotify’s DJ feature, which debuted this past year.

              https://www.youtube.com/watch?v=ok-aNnc0Dko

              We’re used to seeing the polished final result of a personalization feature. Before the year-end award, the making-of backstory, or the behind-the-scenes victory lap, a personalized feature had to be conceived, budgeted, and prioritized. Before any personalization feature goes live in your product or service, it lives amid a backlog of worthy ideas for expressing customer experiences more dynamically.

              So how do you know where to place your personalization bets? How do you design consistent interactions that won’t trip up users or—worse—breed mistrust? We’ve found that for many budgeted programs to justify their ongoing investments, they first needed one or more workshops to convene key stakeholders and internal customers of the technology. Make yours count.

              ​From Big Tech to fledgling startups, we’ve seen the same evolution up close with our clients. In our experiences with working on small and large personalization efforts, a program’s ultimate track record—and its ability to weather tough questions, work steadily toward shared answers, and organize its design and technology efforts—turns on how effectively these prepersonalization activities play out.

              Time and again, we’ve seen effective workshops separate future success stories from unsuccessful efforts, saving countless time, resources, and collective well-being in the process.

              A personalization practice involves a multiyear effort of testing and feature development. It’s not a switch-flip moment in your tech stack. It’s best managed as a backlog that often evolves through three steps: 

              1. customer experience optimization (CXO, also known as A/B testing or experimentation)
              2. always-on automations (whether rules-based or machine-generated)
              3. mature features or standalone product development (such as Spotify’s DJ experience)

              This is why we created our progressive personalization framework and why we’re field-testing an accompanying deck of cards: we believe that there’s a base grammar, a set of “nouns and verbs” that your organization can use to design experiences that are customized, personalized, or automated. You won’t need these cards. But we strongly recommend that you create something similar, whether that might be digital or physical.

              Set your kitchen timer

              How long does it take to cook up a prepersonalization workshop? The surrounding assessment activities that we recommend including can (and often do) span weeks. For the core workshop, we recommend aiming for two to three days. Here’s a summary of our broader approach along with details on the essential first-day activities.

              The full arc of the wider workshop is threefold:

              1. Kickstart: This sets the terms of engagement as you focus on the opportunity as well as the readiness and drive of your team and your leadership. .
              2. Plan your work: This is the heart of the card-based workshop activities where you specify a plan of attack and the scope of work.
              3. Work your plan: This phase is all about creating a competitive environment for team participants to individually pitch their own pilots that each contain a proof-of-concept project, its business case, and its operating model.

              Give yourself at least a day, split into two large time blocks, to power through a concentrated version of those first two phases.

              Kickstart: Whet your appetite

              We call the first lesson the “landscape of connected experience.” It explores the personalization possibilities in your organization. A connected experience, in our parlance, is any UX requiring the orchestration of multiple systems of record on the backend. This could be a content-management system combined with a marketing-automation platform. It could be a digital-asset manager combined with a customer-data platform.

              Spark conversation by naming consumer examples and business-to-business examples of connected experience interactions that you admire, find familiar, or even dislike. This should cover a representative range of personalization patterns, including automated app-based interactions (such as onboarding sequences or wizards), notifications, and recommenders. We have a catalog of these in the cards. Here’s a list of 142 different interactions to jog your thinking.

              This is all about setting the table. What are the possible paths for the practice in your organization? If you want a broader view, here’s a long-form primer and a strategic framework.

              Assess each example that you discuss for its complexity and the level of effort that you estimate that it would take for your team to deliver that feature (or something similar). In our cards, we divide connected experiences into five levels: functions, features, experiences, complete products, and portfolios. Size your own build here. This will help to focus the conversation on the merits of ongoing investment as well as the gap between what you deliver today and what you want to deliver in the future.

              Next, have your team plot each idea on the following 2×2 grid, which lays out the four enduring arguments for a personalized experience. This is critical because it emphasizes how personalization can not only help your external customers but also affect your own ways of working. It’s also a reminder (which is why we used the word argument earlier) of the broader effort beyond these tactical interventions.

              Getting intentional about the desired outcomes is an important component to a large-scale personalization program. Credit: Bucket Studio.

              Each team member should vote on where they see your product or service putting its emphasis. Naturally, you can’t prioritize all of them. The intention here is to flesh out how different departments may view their own upsides to the effort, which can vary from one to the next. Documenting your desired outcomes lets you know how the team internally aligns across representatives from different departments or functional areas.

              The third and final kickstart activity is about naming your personalization gap. Is your customer journey well documented? Will data and privacy compliance be too big of a challenge? Do you have content metadata needs that you have to address? (We’re pretty sure that you do: it’s just a matter of recognizing the relative size of that need and its remedy.) In our cards, we’ve noted a number of program risks, including common team dispositions. Our Detractor card, for example, lists six stakeholder behaviors that hinder progress.

              Effectively collaborating and managing expectations is critical to your success. Consider the potential barriers to your future progress. Press the participants to name specific steps to overcome or mitigate those barriers in your organization. As studies have shown, personalization efforts face many common barriers.

              The largest management consultancies have established practice areas in personalization, and they regularly research program risks and challenges. Credit: Boston Consulting Group.

              At this point, you’ve hopefully discussed sample interactions, emphasized a key area of benefit, and flagged key gaps? Good—you’re ready to continue.

              Hit that test kitchen

              Next, let’s look at what you’ll need to bring your personalization recipes to life. Personalization engines, which are robust software suites for automating and expressing dynamic content, can intimidate new customers. Their capabilities are sweeping and powerful, and they present broad options for how your organization can conduct its activities. This presents the question: Where do you begin when you’re configuring a connected experience?

              What’s important here is to avoid treating the installed software like it were a dream kitchen from some fantasy remodeling project (as one of our client executives memorably put it). These software engines are more like test kitchens where your team can begin devising, tasting, and refining the snacks and meals that will become a part of your personalization program’s regularly evolving menu.

              Progressive personalization, a framework for designing connected experiences. Credit: Bucket Studio and Colin Eagan.

              The ultimate menu of the prioritized backlog will come together over the course of the workshop. And creating “dishes” is the way that you’ll have individual team stakeholders construct personalized interactions that serve their needs or the needs of others.

              The dishes will come from recipes, and those recipes have set ingredients.

              In the same way that ingredients form a recipe, you can also create cards to break down a personalized interaction into its constituent parts. Credit: Bucket Studio and Colin Eagan. Verify your ingredients

              Like a good product manager, you’ll make sure—andyou’ll validate with the right stakeholders present—that you have all the ingredients on hand to cook up your desired interaction (or that you can work out what needs to be added to your pantry). These ingredients include the audience that you’re targeting, content and design elements, the context for the interaction, and your measure for how it’ll come together. 

              This isn’t just about discovering requirements. Documenting your personalizations as a series of if-then statements lets the team: 

              1. compare findings toward a unified approach for developing features, not unlike when artists paint with the same palette; 
              2. specify a consistent set of interactions that users find uniform or familiar; 
              3. and develop parity across performance measurements and key performance indicators too. 

              This helps you streamline your designs and your technical efforts while you deliver a shared palette of core motifs of your personalized or automated experience.

              Compose your recipe

              What ingredients are important to you? Think of a who-what-when-why construct

              • Who are your key audience segments or groups?
              • What kind of content will you give them, in what design elements, and under what circumstances?
              • And for which business and user benefits?

              We first developed these cards and card categories five years ago. We regularly play-test their fit with conference audiences and clients. And we still encounter new possibilities. But they all follow an underlying who-what-when-why logic.

              Here are three examples for a subscription-based reading app, which you can generally follow along with right to left in the cards in the accompanying photo below. 

              1. Nurture personalization: When a guest or an unknown visitor interacts with  a product title, a banner or alert bar appears that makes it easier for them to encounter a related title they may want to read, saving them time.
              2. Welcome automation: When there’s a newly registered user, an email is generated to call out the breadth of the content catalog and to make them a happier subscriber.
              3. Winback automation: Before their subscription lapses or after a recent failed renewal, a user is sent an email that gives them a promotional offer to suggest that they reconsider renewing or to remind them to renew.
              A “nurture” automation may trigger a banner or alert box that promotes content that makes it easier for users to complete a common task, based on behavioral profiling of two user types. Credit: Bucket Studio. A “welcome” automation may be triggered for any user that sends an email to help familiarize them with the breadth of a content library, and this email ideally helps them consider selecting various titles (no matter how much time they devote to reviewing the email’s content itself). Credit: Bucket Studio. A “winback” automation may be triggered for a specific group, such as users with recently failed credit-card transactions or users at risk of churning out of active usage, that present them with a specific offer to mitigate near-future inactivity. Credit: Bucket Studio.

              A useful preworkshop activity may be to think through a first draft of what these cards might be for your organization, although we’ve also found that this process sometimes flows best through cocreating the recipes themselves. Start with a set of blank cards, and begin labeling and grouping them through the design process, eventually distilling them to a refined subset of highly useful candidate cards.

              You can think of the later stages of the workshop as moving from recipes toward a cookbook in focus—like a more nuanced customer-journey mapping. Individual “cooks” will pitch their recipes to the team, using a common jobs-to-be-done format so that measurability and results are baked in, and from there, the resulting collection will be prioritized for finished design and delivery to production.

              Better kitchens require better architecture

              Simplifying a customer experience is a complicated effort for those who are inside delivering it. Beware anyone who says otherwise. With that being said,  “Complicated problems can be hard to solve, but they are addressable with rules and recipes.”

              When personalization becomes a laugh line, it’s because a team is overfitting: they aren’t designing with their best data. Like a sparse pantry, every organization has metadata debt to go along with its technical debt, and this creates a drag on personalization effectiveness. Your AI’s output quality, for example, is indeed limited by your IA. Spotify’s poster-child prowess today was unfathomable before they acquired a seemingly modest metadata startup that now powers its underlying information architecture.

              You can definitely stand the heat…

              Personalization technology opens a doorway into a confounding ocean of possible designs. Only a disciplined and highly collaborative approach will bring about the necessary focus and intention to succeed. So banish the dream kitchen. Instead, hit the test kitchen to save time, preserve job satisfaction and security, and safely dispense with the fanciful ideas that originate upstairs of the doers in your organization. There are meals to serve and mouths to feed.

              This workshop framework gives you a fighting shot at lasting success as well as sound beginnings. Wiring up your information layer isn’t an overnight affair. But if you use the same cookbook and shared recipes, you’ll have solid footing for success. We designed these activities to make your organization’s needs concrete and clear, long before the hazards pile up.

              While there are associated costs toward investing in this kind of technology and product design, your ability to size up and confront your unique situation and your digital capabilities is time well spent. Don’t squander it. The proof, as they say, is in the pudding.

              The Wax and the Wane of the Web

                I offer a single bit of advice to friends and family when they become new parents: When you start to think that you’ve got everything figured out, everything will change. Just as you start to get the hang of feedings, diapers, and regular naps, it’s time for solid food, potty training, and overnight sleeping. When you figure those out, it’s time for preschool and rare naps. The cycle goes on and on.

                The same applies for those of us working in design and development these days. Having worked on the web for almost three decades at this point, I’ve seen the regular wax and wane of ideas, techniques, and technologies. Each time that we as developers and designers get into a regular rhythm, some new idea or technology comes along to shake things up and remake our world.

                How we got here

                I built my first website in the mid-’90s. Design and development on the web back then was a free-for-all, with few established norms. For any layout aside from a single column, we used table elements, often with empty cells containing a single pixel spacer GIF to add empty space. We styled text with numerous font tags, nesting the tags every time we wanted to vary the font style. And we had only three or four typefaces to choose from: Arial, Courier, or Times New Roman. When Verdana and Georgia came out in 1996, we rejoiced because our options had nearly doubled. The only safe colors to choose from were the 216 “web safe” colors known to work across platforms. The few interactive elements (like contact forms, guest books, and counters) were mostly powered by CGI scripts (predominantly written in Perl at the time). Achieving any kind of unique look involved a pile of hacks all the way down. Interaction was often limited to specific pages in a site.

                The birth of web standards

                At the turn of the century, a new cycle started. Crufty code littered with table layouts and font tags waned, and a push for web standards waxed. Newer technologies like CSS got more widespread adoption by browsers makers, developers, and designers. This shift toward standards didn’t happen accidentally or overnight. It took active engagement between the W3C and browser vendors and heavy evangelism from folks like the Web Standards Project to build standards. A List Apart and books like Designing with Web Standards by Jeffrey Zeldman played key roles in teaching developers and designers why standards are important, how to implement them, and how to sell them to their organizations. And approaches like progressive enhancement introduced the idea that content should be available for all browsers—with additional enhancements available for more advanced browsers. Meanwhile, sites like the CSS Zen Garden showcased just how powerful and versatile CSS can be when combined with a solid semantic HTML structure.

                Server-side languages like PHP, Java, and .NET overtook Perl as the predominant back-end processors, and the cgi-bin was tossed in the trash bin. With these better server-side tools came the first era of web applications, starting with content-management systems (particularly in the blogging space with tools like Blogger, Grey Matter, Movable Type, and WordPress). In the mid-2000s, AJAX opened doors for asynchronous interaction between the front end and back end. Suddenly, pages could update their content without needing to reload. A crop of JavaScript frameworks like Prototype, YUI, and jQuery arose to help developers build more reliable client-side interaction across browsers that had wildly varying levels of standards support. Techniques like image replacement let crafty designers and developers display fonts of their choosing. And technologies like Flash made it possible to add animations, games, and even more interactivity.

                These new technologies, standards, and techniques reinvigorated the industry in many ways. Web design flourished as designers and developers explored more diverse styles and layouts. But we still relied on tons of hacks. Early CSS was a huge improvement over table-based layouts when it came to basic layout and text styling, but its limitations at the time meant that designers and developers still relied heavily on images for complex shapes (such as rounded or angled corners) and tiled backgrounds for the appearance of full-length columns (among other hacks). Complicated layouts required all manner of nested floats or absolute positioning (or both). Flash and image replacement for custom fonts was a great start toward varying the typefaces from the big five, but both hacks introduced accessibility and performance problems. And JavaScript libraries made it easy for anyone to add a dash of interaction to pages, although at the cost of doubling or even quadrupling the download size of simple websites.

                The web as software platform

                The symbiosis between the front end and back end continued to improve, and that led to the current era of modern web applications. Between expanded server-side programming languages (which kept growing to include Ruby, Python, Go, and others) and newer front-end tools like React, Vue, and Angular, we could build fully capable software on the web. Alongside these tools came others, including collaborative version control, build automation, and shared package libraries. What was once primarily an environment for linked documents became a realm of infinite possibilities.

                At the same time, mobile devices became more capable, and they gave us internet access in our pockets. Mobile apps and responsive design opened up opportunities for new interactions anywhere and any time.

                This combination of capable mobile devices and powerful development tools contributed to the waxing of social media and other centralized tools for people to connect and consume. As it became easier and more common to connect with others directly on Twitter, Facebook, and even Slack, the desire for hosted personal sites waned. Social media offered connections on a global scale, with both the good and bad that that entails.

                Want a much more extensive history of how we got here, with some other takes on ways that we can improve? Jeremy Keith wrote “Of Time and the Web.” Or check out the “Web Design History Timeline” at the Web Design Museum. Neal Agarwal also has a fun tour through “Internet Artifacts.”

                Where we are now

                In the last couple of years, it’s felt like we’ve begun to reach another major inflection point. As social-media platforms fracture and wane, there’s been a growing interest in owning our own content again. There are many different ways to make a website, from the tried-and-true classic of hosting plain HTML files to static site generators to content management systems of all flavors. The fracturing of social media also comes with a cost: we lose crucial infrastructure for discovery and connection. Webmentions, RSS, ActivityPub, and other tools of the IndieWeb can help with this, but they’re still relatively underimplemented and hard to use for the less nerdy. We can build amazing personal websites and add to them regularly, but without discovery and connection, it can sometimes feel like we may as well be shouting into the void.

                Browser support for CSS, JavaScript, and other standards like web components has accelerated, especially through efforts like Interop. New technologies gain support across the board in a fraction of the time that they used to. I often learn about a new feature and check its browser support only to find that its coverage is already above 80 percent. Nowadays, the barrier to using newer techniques often isn’t browser support but simply the limits of how quickly designers and developers can learn what’s available and how to adopt it.

                Today, with a few commands and a couple of lines of code, we can prototype almost any idea. All the tools that we now have available make it easier than ever to start something new. But the upfront cost that these frameworks may save in initial delivery eventually comes due as upgrading and maintaining them becomes a part of our technical debt.

                If we rely on third-party frameworks, adopting new standards can sometimes take longer since we may have to wait for those frameworks to adopt those standards. These frameworks—which used to let us adopt new techniques sooner—have now become hindrances instead. These same frameworks often come with performance costs too, forcing users to wait for scripts to load before they can read or interact with pages. And when scripts fail (whether through poor code, network issues, or other environmental factors), there’s often no alternative, leaving users with blank or broken pages.

                Where do we go from here?

                Today’s hacks help to shape tomorrow’s standards. And there’s nothing inherently wrong with embracing hacks—for now—to move the present forward. Problems only arise when we’re unwilling to admit that they’re hacks or we hesitate to replace them. So what can we do to create the future we want for the web?

                Build for the long haul. Optimize for performance, for accessibility, and for the user. Weigh the costs of those developer-friendly tools. They may make your job a little easier today, but how do they affect everything else? What’s the cost to users? To future developers? To standards adoption? Sometimes the convenience may be worth it. Sometimes it’s just a hack that you’ve grown accustomed to. And sometimes it’s holding you back from even better options.

                Start from standards. Standards continue to evolve over time, but browsers have done a remarkably good job of continuing to support older standards. The same isn’t always true of third-party frameworks. Sites built with even the hackiest of HTML from the ’90s still work just fine today. The same can’t always be said of sites built with frameworks even after just a couple years.

                Design with care. Whether your craft is code, pixels, or processes, consider the impacts of each decision. The convenience of many a modern tool comes at the cost of not always understanding the underlying decisions that have led to its design and not always considering the impact that those decisions can have. Rather than rushing headlong to “move fast and break things,” use the time saved by modern tools to consider more carefully and design with deliberation.

                Always be learning. If you’re always learning, you’re also growing. Sometimes it may be hard to pinpoint what’s worth learning and what’s just today’s hack. You might end up focusing on something that won’t matter next year, even if you were to focus solely on learning standards. (Remember XHTML?) But constant learning opens up new connections in your brain, and the hacks that you learn one day may help to inform different experiments another day.

                Play, experiment, and be weird! This web that we’ve built is the ultimate experiment. It’s the single largest human endeavor in history, and yet each of us can create our own pocket within it. Be courageous and try new things. Build a playground for ideas. Make goofy experiments in your own mad science lab. Start your own small business. There has never been a more empowering place to be creative, take risks, and explore what we’re capable of.

                Share and amplify. As you experiment, play, and learn, share what’s worked for you. Write on your own website, post on whichever social media site you prefer, or shout it from a TikTok. Write something for A List Apart! But take the time to amplify others too: find new voices, learn from them, and share what they’ve taught you.

                Go forth and make

                As designers and developers for the web (and beyond), we’re responsible for building the future every day, whether that may take the shape of personal websites, social media tools used by billions, or anything in between. Let’s imbue our values into the things that we create, and let’s make the web a better place for everyone. Create that thing that only you are uniquely qualified to make. Then share it, make it better, make it again, or make something new. Learn. Make. Share. Grow. Rinse and repeat. Every time you think that you’ve mastered the web, everything will change.

                Opportunities for AI in Accessibility

                  In reading Joe Dolson’s recent piece on the intersection of AI and accessibility, I absolutely appreciated the skepticism that he has for AI in general as well as for the ways that many have been using it. In fact, I’m very skeptical of AI myself, despite my role at Microsoft as an accessibility innovation strategist who helps run the AI for Accessibility grant program. As with any tool, AI can be used in very constructive, inclusive, and accessible ways; and it can also be used in destructive, exclusive, and harmful ones. And there are a ton of uses somewhere in the mediocre middle as well.

                  I’d like you to consider this a “yes… and” piece to complement Joe’s post. I’m not trying to refute any of what he’s saying but rather provide some visibility to projects and opportunities where AI can make meaningful differences for people with disabilities. To be clear, I’m not saying that there aren’t real risks or pressing issues with AI that need to be addressed—there are, and we’ve needed to address them, like, yesterday—but I want to take a little time to talk about what’s possible in hopes that we’ll get there one day.

                  Alternative text

                  Joe’s piece spends a lot of time talking about computer-vision models generating alternative text. He highlights a ton of valid issues with the current state of things. And while computer-vision models continue to improve in the quality and richness of detail in their descriptions, their results aren’t great. As he rightly points out, the current state of image analysis is pretty poor—especially for certain image types—in large part because current AI systems examine images in isolation rather than within the contexts that they’re in (which is a consequence of having separate “foundation” models for text analysis and image analysis). Today’s models aren’t trained to distinguish between images that are contextually relevant (that should probably have descriptions) and those that are purely decorative (which might not need a description) either. Still, I still think there’s potential in this space.

                  As Joe mentions, human-in-the-loop authoring of alt text should absolutely be a thing. And if AI can pop in to offer a starting point for alt text—even if that starting point might be a prompt saying What is this BS? That’s not right at all… Let me try to offer a starting point—I think that’s a win.

                  Taking things a step further, if we can specifically train a model to analyze image usage in context, it could help us more quickly identify which images are likely to be decorative and which ones likely require a description. That will help reinforce which contexts call for image descriptions and it’ll improve authors’ efficiency toward making their pages more accessible.

                  While complex images—like graphs and charts—are challenging to describe in any sort of succinct way (even for humans), the image example shared in the GPT4 announcement points to an interesting opportunity as well. Let’s suppose that you came across a chart whose description was simply the title of the chart and the kind of visualization it was, such as: Pie chart comparing smartphone usage to feature phone usage among US households making under $30,000 a year. (That would be a pretty awful alt text for a chart since that would tend to leave many questions about the data unanswered, but then again, let’s suppose that that was the description that was in place.) If your browser knew that that image was a pie chart (because an onboard model concluded this), imagine a world where users could ask questions like these about the graphic:

                  • Do more people use smartphones or feature phones?
                  • How many more?
                  • Is there a group of people that don’t fall into either of these buckets?
                  • How many is that?

                  Setting aside the realities of large language model (LLM) hallucinations—where a model just makes up plausible-sounding “facts”—for a moment, the opportunity to learn more about images and data in this way could be revolutionary for blind and low-vision folks as well as for people with various forms of color blindness, cognitive disabilities, and so on. It could also be useful in educational contexts to help people who can see these charts, as is, to understand the data in the charts.

                  Taking things a step further: What if you could ask your browser to simplify a complex chart? What if you could ask it to isolate a single line on a line graph? What if you could ask your browser to transpose the colors of the different lines to work better for form of color blindness you have? What if you could ask it to swap colors for patterns? Given these tools’ chat-based interfaces and our existing ability to manipulate images in today’s AI tools, that seems like a possibility.

                  Now imagine a purpose-built model that could extract the information from that chart and convert it to another format. For example, perhaps it could turn that pie chart (or better yet, a series of pie charts) into more accessible (and useful) formats, like spreadsheets. That would be amazing!

                  Matching algorithms

                  Safiya Umoja Noble absolutely hit the nail on the head when she titled her book Algorithms of Oppression. While her book was focused on the ways that search engines reinforce racism, I think that it’s equally true that all computer models have the potential to amplify conflict, bias, and intolerance. Whether it’s Twitter always showing you the latest tweet from a bored billionaire, YouTube sending us into a Q-hole, or Instagram warping our ideas of what natural bodies look like, we know that poorly authored and maintained algorithms are incredibly harmful. A lot of this stems from a lack of diversity among the people who shape and build them. When these platforms are built with inclusively baked in, however, there’s real potential for algorithm development to help people with disabilities.

                  Take Mentra, for example. They are an employment network for neurodivergent people. They use an algorithm to match job seekers with potential employers based on over 75 data points. On the job-seeker side of things, it considers each candidate’s strengths, their necessary and preferred workplace accommodations, environmental sensitivities, and so on. On the employer side, it considers each work environment, communication factors related to each job, and the like. As a company run by neurodivergent folks, Mentra made the decision to flip the script when it came to typical employment sites. They use their algorithm to propose available candidates to companies, who can then connect with job seekers that they are interested in; reducing the emotional and physical labor on the job-seeker side of things.

                  When more people with disabilities are involved in the creation of algorithms, that can reduce the chances that these algorithms will inflict harm on their communities. That’s why diverse teams are so important.

                  Imagine that a social media company’s recommendation engine was tuned to analyze who you’re following and if it was tuned to prioritize follow recommendations for people who talked about similar things but who were different in some key ways from your existing sphere of influence. For example, if you were to follow a bunch of nondisabled white male academics who talk about AI, it could suggest that you follow academics who are disabled or aren’t white or aren’t male who also talk about AI. If you took its recommendations, perhaps you’d get a more holistic and nuanced understanding of what’s happening in the AI field. These same systems should also use their understanding of biases about particular communities—including, for instance, the disability community—to make sure that they aren’t recommending any of their users follow accounts that perpetuate biases against (or, worse, spewing hate toward) those groups.

                  Other ways that AI can helps people with disabilities

                  If I weren’t trying to put this together between other tasks, I’m sure that I could go on and on, providing all kinds of examples of how AI could be used to help people with disabilities, but I’m going to make this last section into a bit of a lightning round. In no particular order:

                  • Voice preservation. You may have seen the VALL-E paper or Apple’s Global Accessibility Awareness Day announcement or you may be familiar with the voice-preservation offerings from Microsoft, Acapela, or others. It’s possible to train an AI model to replicate your voice, which can be a tremendous boon for people who have ALS (Lou Gehrig’s disease) or motor-neuron disease or other medical conditions that can lead to an inability to talk. This is, of course, the same tech that can also be used to create audio deepfakes, so it’s something that we need to approach responsibly, but the tech has truly transformative potential.
                  • Voice recognition. Researchers like those in the Speech Accessibility Project are paying people with disabilities for their help in collecting recordings of people with atypical speech. As I type, they are actively recruiting people with Parkinson’s and related conditions, and they have plans to expand this to other conditions as the project progresses. This research will result in more inclusive data sets that will let more people with disabilities use voice assistants, dictation software, and voice-response services as well as control their computers and other devices more easily, using only their voice.
                  • Text transformation. The current generation of LLMs is quite capable of adjusting existing text content without injecting hallucinations. This is hugely empowering for people with cognitive disabilities who may benefit from text summaries or simplified versions of text or even text that’s prepped for Bionic Reading.
                  The importance of diverse teams and data

                  We need to recognize that our differences matter. Our lived experiences are influenced by the intersections of the identities that we exist in. These lived experiences—with all their complexities (and joys and pain)—are valuable inputs to the software, services, and societies that we shape. Our differences need to be represented in the data that we use to train new models, and the folks who contribute that valuable information need to be compensated for sharing it with us. Inclusive data sets yield more robust models that foster more equitable outcomes.

                  Want a model that doesn’t demean or patronize or objectify people with disabilities? Make sure that you have content about disabilities that’s authored by people with a range of disabilities, and make sure that that’s well represented in the training data.

                  Want a model that doesn’t use ableist language? You may be able to use existing data sets to build a filter that can intercept and remediate ableist language before it reaches readers. That being said, when it comes to sensitivity reading, AI models won’t be replacing human copy editors anytime soon. 

                  Want a coding copilot that gives you accessible recommendations from the jump? Train it on code that you know to be accessible.

                  I have no doubt that AI can and will harm people… today, tomorrow, and well into the future. But I also believe that we can acknowledge that and, with an eye towards accessibility (and, more broadly, inclusion), make thoughtful, considerate, and intentional changes in our approaches to AI that will reduce harm over time as well. Today, tomorrow, and well into the future.

                  Many thanks to Kartik Sawhney for helping me with the development of this piece, Ashley Bischoff for her invaluable editorial assistance, and, of course, Joe Dolson for the prompt.

                  I am a creative.

                    I am a creative. What I do is alchemy. It is a mystery. I do not so much do it, as let it be done through me.

                    I am a creative. Not all creative people like this label. Not all see themselves this way. Some creative people see science in what they do. That is their truth, and I respect it. Maybe I even envy them, a little. But my process is different—my being is different.

                    Apologizing and qualifying in advance is a distraction. That’s what my brain does to sabotage me. I set it aside for now. I can come back later to apologize and qualify. After I’ve said what I came to say. Which is hard enough. 

                    Except when it is easy and flows like a river of wine.

                    Sometimes it does come that way. Sometimes what I need to create comes in an instant. I have learned not to say it at that moment, because if you admit that sometimes the idea just comes and it is the best idea and you know it is the best idea, they think you don’t work hard enough.

                    Sometimes I work and work and work until the idea comes. Sometimes it comes instantly and I don’t tell anyone for three days. Sometimes I’m so excited by the idea that came instantly that I blurt it out, can’t help myself. Like a boy who found a prize in his Cracker Jacks. Sometimes I get away with this. Sometimes other people agree: yes, that is the best idea. Most times they don’t and I regret having  given way to enthusiasm. 

                    Enthusiasm is best saved for the meeting where it will make a difference. Not the casual get-together that precedes that meeting by two other meetings. Nobody knows why we have all these meetings. We keep saying we’re doing away with them, but then just finding other ways to have them. Sometimes they are even good. But other times they are a distraction from the actual work. The proportion between when meetings are useful, and when they are a pitiful distraction, varies, depending on what you do and where you do it. And who you are and how you do it. Again I digress. I am a creative. That is the theme.

                    Sometimes many hours of hard and patient work produce something that is barely serviceable. Sometimes I have to accept that and move on to the next project.

                    Don’t ask about process. I am a creative.

                    I am a creative. I don’t control my dreams. And I don’t control my best ideas.

                    I can hammer away, surround myself with facts or images, and sometimes that works. I can go for a walk, and sometimes that works. I can be making dinner and there’s a Eureka having nothing to do with sizzling oil and bubbling pots. Often I know what to do the instant I wake up. And then, almost as often, as I become conscious and part of the world again, the idea that would have saved me turns to vanishing dust in a mindless wind of oblivion. For creativity, I believe, comes from that other world. The one we enter in dreams, and perhaps, before birth and after death. But that’s for poets to wonder, and I am not a poet. I am a creative. And it’s for theologians to mass armies about in their creative world that they insist is real. But that is another digression. And a depressing one. Maybe on a much more important topic than whether I am a creative or not. But still a digression from what I came here to say.

                    Sometimes the process is avoidance. And agony. You know the cliché about the tortured artist? It’s true, even when the artist (and let’s put that noun in quotes) is trying to write a soft drink jingle, a callback in a tired sitcom, a budget request.

                    Some people who hate being called creative may be closeted creatives, but that’s between them and their gods. No offense meant. Your truth is true, too. But mine is for me. 

                    Creatives recognize creatives.

                    Creatives recognize creatives like queers recognize queers, like real rappers recognize real rappers, like cons know cons. Creatives feel massive respect for creatives. We love, honor, emulate, and practically deify the great ones. To deify any human is, of course, a tragic mistake. We have been warned. We know better. We know people are just people. They squabble, they are lonely, they regret their most important decisions, they are poor and hungry, they can be cruel, they can be just as stupid as we can, because, like us, they are clay. But. But. But they make this amazing thing. They birth something that did not exist before them, and could not exist without them. They are the mothers of ideas. And I suppose, since it’s just lying there, I have to add that they are the mothers of invention. Ba dum bum! OK, that’s done. Continue.

                    Creatives belittle our own small achievements, because we compare them to those of the great ones. Beautiful animation! Well, I’m no Miyazaki. Now THAT is greatness. That is greatness straight from the mind of God. This half-starved little thing that I made? It more or less fell off the back of the turnip truck. And the turnips weren’t even fresh.

                    Creatives knows that, at best, they are Salieri. Even the creatives who are Mozart believe that. 

                    I am a creative. I haven’t worked in advertising in 30 years, but in my nightmares, it’s my former creative directors who judge me. And they are right to do so. I am too lazy, too facile, and when it really counts, my mind goes blank. There is no pill for creative dysfunction.

                    I am a creative. Every deadline I make is an adventure that makes Indiana Jones look like a pensioner snoring in a deck chair. The longer I remain a creative, the faster I am when I do my work and the longer I brood and walk in circles and stare blankly before I do that work. 

                    I am still 10 times faster than people who are not creative, or people who have only been creative a short while, or people who have only been professionally creative a short while. It’s just that, before I work 10 times as fast as they do, I spend twice as long as they do putting the work off. I am that confident in my ability to do a great job when I put my mind to it. I am that addicted to the adrenaline rush of postponement. I am still that afraid of the jump.

                    I am not an artist.

                    I am a creative. Not an artist. Though I dreamed, as a lad, of someday being that. Some of us belittle our gifts and dislike ourselves because we are not Michelangelos and Warhols. That is narcissism—but at least we aren’t in politics.

                    I am a creative. Though I believe in reason and science, I decide by intuition and impulse. And live with what follows—the catastrophes as well as the triumphs. 

                    I am a creative. Every word I’ve said here will annoy other creatives, who see things differently. Ask two creatives a question, get three opinions. Our disagreement, our passion about it, and our commitment to our own truth are, at least to me, the proofs that we are creatives, no matter how we may feel about it.

                    I am a creative. I lament my lack of taste in the areas about which I know very little, which is to say almost all areas of human knowledge. And I trust my taste above all other things in the areas closest to my heart, or perhaps, more accurately, to my obsessions. Without my obsessions, I would probably have to spend my time looking life in the eye, and almost none of us can do that for long. Not honestly. Not really. Because much in life, if you really look at it, is unbearable.

                    I am a creative. I believe, as a parent believes, that when I am gone, some small good part of me will carry on in the mind of at least one other person.

                    Working saves me from worrying about work.

                    I am a creative. I live in dread of my small gift suddenly going away.

                    I am a creative. I am too busy making the next thing to spend too much time deeply considering that almost nothing I make will come anywhere near the greatness I comically aspire to.

                    I am a creative. I believe in the ultimate mystery of process. I believe in it so much, I am even fool enough to publish an essay I dictated into a tiny machine and didn’t take time to review or revise. I won’t do this often, I promise. But I did it just now, because, as afraid as I might be of your seeing through my pitiful gestures toward the beautiful, I was even more afraid of forgetting what I came to say. 

                    There. I think I’ve said it. 

                    Humility: An Essential Value

                      Humility, a designer’s essential value—that has a nice ring to it. What about humility, an office manager’s essential value? Or a dentist’s? Or a librarian’s? They all sound great. When humility is our guiding light, the path is always open for fulfillment, evolution, connection, and engagement. In this chapter, we’re going to talk about why.

                      That said, this is a book for designers, and to that end, I’d like to start with a story—well, a journey, really. It’s a personal one, and I’m going to make myself a bit vulnerable along the way. I call it:

                      The Tale of Justin’s Preposterous Pate

                      When I was coming out of art school, a long-haired, goateed neophyte, print was a known quantity to me; design on the web, however, was rife with complexities to navigate and discover, a problem to be solved. Though I had been formally trained in graphic design, typography, and layout, what fascinated me was how these traditional skills might be applied to a fledgling digital landscape. This theme would ultimately shape the rest of my career.

                      So rather than graduate and go into print like many of my friends, I devoured HTML and JavaScript books into the wee hours of the morning and taught myself how to code during my senior year. I wanted—nay, needed—to better understand the underlying implications of what my design decisions would mean once rendered in a browser.

                      The late ’90s and early 2000s were the so-called “Wild West” of web design. Designers at the time were all figuring out how to apply design and visual communication to the digital landscape. What were the rules? How could we break them and still engage, entertain, and convey information? At a more macro level, how could my values, inclusive of humility, respect, and connection, align in tandem with that? I was hungry to find out.

                      Though I’m talking about a different era, those are timeless considerations between non-career interactions and the world of design. What are your core passions, or values, that transcend medium? It’s essentially the same concept we discussed earlier on the direct parallels between what fulfills you, agnostic of the tangible or digital realms; the core themes are all the same.

                      First within tables, animated GIFs, Flash, then with Web Standards, divs, and CSS, there was personality, raw unbridled creativity, and unique means of presentment that often defied any semblance of a visible grid. Splash screens and “browser requirement” pages aplenty. Usability and accessibility were typically victims of such a creation, but such paramount facets of any digital design were largely (and, in hindsight, unfairly) disregarded at the expense of experimentation.

                      For example, this iteration of my personal portfolio site (“the pseudoroom”) from that era was experimental, if not a bit heavy- handed, in the visual communication of the concept of a living sketchbook. Very skeuomorphic. I collaborated with fellow designer and dear friend Marc Clancy (now a co-founder of the creative project organizing app Milanote) on this one, where we’d first sketch and then pass a Photoshop file back and forth to trick things out and play with varied user interactions. Then, I’d break it down and code it into a digital layout.

                      Figure 1: “the pseudoroom” website, hitting the sketchbook metaphor hard.

                      Along with design folio pieces, the site also offered free downloads for Mac OS customizations: desktop wallpapers that were effectively design experimentation, custom-designed typefaces, and desktop icons.

                      From around the same time, GUI Galaxy was a design, pixel art, and Mac-centric news portal some graphic designer friends and I conceived, designed, developed, and deployed.

                      Figure 2: GUI Galaxy, web standards-compliant design news portal

                      Design news portals were incredibly popular during this period, featuring (what would now be considered) Tweet-size, small-format snippets of pertinent news from the categories I previously mentioned. If you took Twitter, curated it to a few categories, and wrapped it in a custom-branded experience, you’d have a design news portal from the late 90s / early 2000s.

                      We as designers had evolved and created a bandwidth-sensitive, web standards award-winning, much more accessibility-conscious website. Still ripe with experimentation, yet more mindful of equitable engagement. You can see a couple of content panes here, noting general news (tech, design) and Mac-centric news below. We also offered many of the custom downloads I cited before as present on my folio site but branded and themed to GUI Galaxy.

                      The site’s backbone was a homegrown CMS, with the presentation layer consisting of global design + illustration + news author collaboration. And the collaboration effort here, in addition to experimentation on a ‘brand’ and content delivery, was hitting my core. We were designing something bigger than any single one of us and connecting with a global audience.

                      Collaboration and connection transcend medium in their impact, immensely fulfilling me as a designer.

                      Now, why am I taking you down this trip of design memory lane? Two reasons.

                      First, there’s a reason for the nostalgia for that design era (the “Wild West” era, as I called it earlier): the inherent exploration, personality, and creativity that saturated many design portals and personal portfolio sites. Ultra-finely detailed pixel art UI, custom illustration, bespoke vector graphics, all underpinned by a strong design community.

                      Today’s web design has been in a period of stagnation. I suspect there’s a strong chance you’ve seen a site whose structure looks something like this: a hero image / banner with text overlaid, perhaps with a lovely rotating carousel of images (laying the snark on heavy there), a call to action, and three columns of sub-content directly beneath. Maybe an icon library is employed with selections that vaguely relate to their respective content.

                      Design, as it’s applied to the digital landscape, is in dire need of thoughtful layout, typography, and visual engagement that goes hand-in-hand with all the modern considerations we now know are paramount: usability. Accessibility. Load times and bandwidth- sensitive content delivery. A responsive presentation that meets human beings wherever they’re engaging from. We must be mindful of, and respectful toward, those concerns—but not at the expense of creativity of visual communication or via replicating cookie-cutter layouts.

                      Pixel Problems

                      Websites during this period were often designed and built on Macs whose OS and desktops looked something like this. This is Mac OS 7.5, but 8 and 9 weren’t that different.

                      Figure 3: A Mac OS 7.5-centric desktop.

                      Desktop icons fascinated me: how could any single one, at any given point, stand out to get my attention? In this example, the user’s desktop is tidy, but think of a more realistic example with icon pandemonium. Or, say an icon was part of a larger system grouping (fonts, extensions, control panels)—how did it also maintain cohesion amongst a group?

                      These were 32 x 32 pixel creations, utilizing a 256-color palette, designed pixel-by-pixel as mini mosaics. To me, this was the embodiment of digital visual communication under such ridiculous constraints. And often, ridiculous restrictions can yield the purification of concept and theme.

                      So I began to research and do my homework. I was a student of this new medium, hungry to dissect, process, discover, and make it my own.

                      Expanding upon the notion of exploration, I wanted to see how I could push the limits of a 32x32 pixel grid with that 256-color palette. Those ridiculous constraints forced a clarity of concept and presentation that I found incredibly appealing. The digital gauntlet had been tossed, and that challenge fueled me. And so, in my dorm room into the wee hours of the morning, I toiled away, bringing conceptual sketches into mini mosaic fruition.

                      These are some of my creations, utilizing the only tool available at the time to create icons called ResEdit. ResEdit was a clunky, built-in Mac OS utility not really made for exactly what we were using it for. At the core of all of this work: Research. Challenge. Problem- solving. Again, these core connection-based values are agnostic of medium.

                      Figure 4: A selection of my pixel art design, 32x32 pixel canvas, 8-bit palette

                      There’s one more design portal I want to talk about, which also serves as the second reason for my story to bring this all together.

                      This is K10k, short for Kaliber 1000. K10k was founded in 1998 by Michael Schmidt and Toke Nygaard, and was the design news portal on the web during this period. With its pixel art-fueled presentation, ultra-focused care given to every facet and detail, and with many of the more influential designers of the time who were invited to be news authors on the site, well... it was the place to be, my friend. With respect where respect is due, GUI Galaxy’s concept was inspired by what these folks were doing.

                      Figure 5: The K10k website

                      For my part, the combination of my web design work and pixel art exploration began to get me some notoriety in the design scene. Eventually, K10k noticed and added me as one of their very select group of news authors to contribute content to the site.

                      Amongst my personal work and side projects—and now with this inclusion—in the design community, this put me on the map. My design work also began to be published in various printed collections, in magazines domestically and overseas, and featured on other design news portals. With that degree of success while in my early twenties, something else happened:

                      I evolved—devolved, really—into a colossal asshole (and in just about a year out of art school, no less). The press and the praise became what fulfilled me, and they went straight to my head. They inflated my ego. I actually felt somewhat superior to my fellow designers.

                      The casualties? My design stagnated. Its evolution—my evolution— stagnated.

                      I felt so supremely confident in my abilities that I effectively stopped researching and discovering. When previously sketching concepts or iterating ideas in lead was my automatic step one, I instead leaped right into Photoshop. I drew my inspiration from the smallest of sources (and with blinders on). Any critique of my work from my peers was often vehemently dismissed. The most tragic loss: I had lost touch with my values.

                      My ego almost cost me some of my friendships and burgeoning professional relationships. I was toxic in talking about design and in collaboration. But thankfully, those same friends gave me a priceless gift: candor. They called me out on my unhealthy behavior.

                      Admittedly, it was a gift I initially did not accept but ultimately was able to deeply reflect upon. I was soon able to accept, and process, and course correct. The realization laid me low, but the re-awakening was essential. I let go of the “reward” of adulation and re-centered upon what stoked the fire for me in art school. Most importantly: I got back to my core values.

                      Always Students

                      Following that short-term regression, I was able to push forward in my personal design and career. And I could self-reflect as I got older to facilitate further growth and course correction as needed.

                      As an example, let’s talk about the Large Hadron Collider. The LHC was designed “to help answer some of the fundamental open questions in physics, which concern the basic laws governing the interactions and forces among the elementary objects, the deep structure of space and time, and in particular the interrelation between quantum mechanics and general relativity.” Thanks, Wikipedia.

                      Around fifteen years ago, in one of my earlier professional roles, I designed the interface for the application that generated the LHC’s particle collision diagrams. These diagrams are the rendering of what’s actually happening inside the Collider during any given particle collision event and are often considered works of art unto themselves.

                      Designing the interface for this application was a fascinating process for me, in that I worked with Fermilab physicists to understand what the application was trying to achieve, but also how the physicists themselves would be using it. To that end, in this role,

                      I cut my teeth on usability testing, working with the Fermilab team to iterate and improve the interface. How they spoke and what they spoke about was like an alien language to me. And by making myself humble and working under the mindset that I was but a student, I made myself available to be a part of their world to generate that vital connection.

                      I also had my first ethnographic observation experience: going to the Fermilab location and observing how the physicists used the tool in their actual environment, on their actual terminals. For example, one takeaway was that due to the level of ambient light-driven contrast within the facility, the data columns ended up using white text on a dark gray background instead of black text-on-white. This enabled them to pore over reams of data during the day and ease their eye strain. And Fermilab and CERN are government entities with rigorous accessibility standards, so my knowledge in that realm also grew. The barrier-free design was another essential form of connection.

                      So to those core drivers of my visual problem-solving soul and ultimate fulfillment: discovery, exposure to new media, observation, human connection, and evolution. What opened the door for those values was me checking my ego before I walked through it.

                      An evergreen willingness to listen, learn, understand, grow, evolve, and connect yields our best work. In particular, I want to focus on the words ‘grow’ and ‘evolve’ in that statement. If we are always students of our craft, we are also continually making ourselves available to evolve. Yes, we have years of applicable design study under our belt. Or the focused lab sessions from a UX bootcamp. Or the monogrammed portfolio of our work. Or, ultimately, decades of a career behind us.

                      But all that said: experience does not equal “expert.”

                      As soon as we close our minds via an inner monologue of ‘knowing it all’ or branding ourselves a “#thoughtleader” on social media, the designer we are is our final form. The designer we can be will never exist.

                      Personalization Pyramid: A Framework for Designing with User Data

                        As a UX professional in today’s data-driven landscape, it’s increasingly likely that you’ve been asked to design a personalized digital experience, whether it’s a public website, user portal, or native application. Yet while there continues to be no shortage of marketing hype around personalization platforms, we still have very few standardized approaches for implementing personalized UX.

                        That’s where we come in. After completing dozens of personalization projects over the past few years, we gave ourselves a goal: could you create a holistic personalization framework specifically for UX practitioners? The Personalization Pyramid is a designer-centric model for standing up human-centered personalization programs, spanning data, segmentation, content delivery, and overall goals. By using this approach, you will be able to understand the core components of a contemporary, UX-driven personalization program (or at the very least know enough to get started). 

                        Growing tools for personalization: According to a Dynamic Yield survey, 39% of respondents felt support is available on-demand when a business case is made for it (up 15% from 2020).

                        Source: “The State of Personalization Maturity – Q4 2021” Dynamic Yield conducted its annual maturity survey across roles and sectors in the Americas (AMER), Europe and the Middle East (EMEA), and the Asia-Pacific (APAC) regions. This marks the fourth consecutive year publishing our research, which includes more than 450 responses from individuals in the C-Suite, Marketing, Merchandising, CX, Product, and IT.

                        Getting Started

                        For the sake of this article, we’ll assume you’re already familiar with the basics of digital personalization. A good overview can be found here: Website Personalization Planning. While UX projects in this area can take on many different forms, they often stem from similar starting points.      

                        Common scenarios for starting a personalization project:

                        • Your organization or client purchased a content management system (CMS) or marketing automation platform (MAP) or related technology that supports personalization
                        • The CMO, CDO, or CIO has identified personalization as a goal
                        • Customer data is disjointed or ambiguous
                        • You are running some isolated targeting campaigns or A/B testing
                        • Stakeholders disagree on personalization approach
                        • Mandate of customer privacy rules (e.g. GDPR) requires revisiting existing user targeting practices
                        Workshopping personalization at a conference.

                        Regardless of where you begin, a successful personalization program will require the same core building blocks. We’ve captured these as the “levels” on the pyramid. Whether you are a UX designer, researcher, or strategist, understanding the core components can help make your contribution successful.  

                        From the ground up: Soup-to-nuts personalization, without going nuts.

                        From top to bottom, the levels include:

                        1. North Star: What larger strategic objective is driving the personalization program? 
                        2. Goals: What are the specific, measurable outcomes of the program? 
                        3. Touchpoints: Where will the personalized experience be served?
                        4. Contexts and Campaigns: What personalization content will the user see?
                        5. User Segments: What constitutes a unique, usable audience? 
                        6. Actionable Data: What reliable and authoritative data is captured by our technical platform to drive personalization?  
                        7. Raw Data: What wider set of data is conceivably available (already in our setting) allowing you to personalize?

                        We’ll go through each of these levels in turn. To help make this actionable, we created an accompanying deck of cards to illustrate specific examples from each level. We’ve found them helpful in personalization brainstorming sessions, and will include examples for you here.

                        Personalization pack: Deck of cards to help kickstart your personalization brainstorming. Starting at the Top

                        The components of the pyramid are as follows:

                        North Star

                        A north star is what you are aiming for overall with your personalization program (big or small). The North Star defines the (one) overall mission of the personalization program. What do you wish to accomplish? North Stars cast a shadow. The bigger the star, the bigger the shadow. Example of North Starts might include: 

                        1. Function: Personalize based on basic user inputs. Examples: “Raw” notifications, basic search results, system user settings and configuration options, general customization, basic optimizations
                        2. Feature: Self-contained personalization componentry. Examples: “Cooked” notifications, advanced optimizations (geolocation), basic dynamic messaging, customized modules, automations, recommenders
                        3. Experience: Personalized user experiences across multiple interactions and user flows. Examples: Email campaigns, landing pages, advanced messaging (i.e. C2C chat) or conversational interfaces, larger user flows and content-intensive optimizations (localization).
                        4. Product: Highly differentiating personalized product experiences. Examples: Standalone, branded experiences with personalization at their core, like the “algotorial” playlists by Spotify such as Discover Weekly.
                        North star cards. These can help orient your team towards a common goal that personalization will help achieve; Also, these are useful for characterizing the end-state ambition of the presently stated personalization effort. Goals

                        As in any good UX design, personalization can help accelerate designing with customer intentions. Goals are the tactical and measurable metrics that will prove the overall program is successful. A good place to start is with your current analytics and measurement program and metrics you can benchmark against. In some cases, new goals may be appropriate. The key thing to remember is that personalization itself is not a goal, rather it is a means to an end. Common goals include:

                        • Conversion
                        • Time on task
                        • Net promoter score (NPS)
                        • Customer satisfaction 
                        Goal cards. Examples of some common KPIs related to personalization that are concrete and measurable. Touchpoints

                        Touchpoints are where the personalization happens. As a UX designer, this will be one of your largest areas of responsibility. The touchpoints available to you will depend on how your personalization and associated technology capabilities are instrumented, and should be rooted in improving a user’s experience at a particular point in the journey. Touchpoints can be multi-device (mobile, in-store, website) but also more granular (web banner, web pop-up etc.). Here are some examples:

                        Channel-level Touchpoints

                        • Email: Role
                        • Email: Time of open
                        • In-store display (JSON endpoint)
                        • Native app
                        • Search

                        Wireframe-level Touchpoints

                        • Web overlay
                        • Web alert bar
                        • Web banner
                        • Web content block
                        • Web menu
                        Touchpoint cards. Examples of common personalization touchpoints: these can vary from narrow (e.g., email) to broad (e.g., in-store).

                        If you’re designing for web interfaces, for example, you will likely need to include personalized “zones” in your wireframes. The content for these can be presented programmatically in touchpoints based on our next step, contexts and campaigns.

                        Targeted Zones: Examples from Kibo of personalized “zones” on page-level wireframes occurring at various stages of a user journey (Engagement phase at left and Purchase phase at right.)

                        Source: “Essential Guide to End-to-End Personaliztion” by Kibo. Contexts and Campaigns

                        Once you’ve outlined some touchpoints, you can consider the actual personalized content a user will receive. Many personalization tools will refer to these as “campaigns” (so, for example, a campaign on a web banner for new visitors to the website). These will programmatically be shown at certain touchpoints to certain user segments, as defined by user data. At this stage, we find it helpful to consider two separate models: a context model and a content model. The context helps you consider the level of engagement of the user at the personalization moment, for example a user casually browsing information vs. doing a deep-dive. Think of it in terms of information retrieval behaviors. The content model can then help you determine what type of personalization to serve based on the context (for example, an “Enrich” campaign that shows related articles may be a suitable supplement to extant content).

                        Personalization Context Model:

                        1. Browse
                        2. Skim
                        3. Nudge
                        4. Feast

                        Personalization Content Model:

                        1. Alert
                        2. Make Easier
                        3. Cross-Sell
                        4. Enrich

                        We’ve written extensively about each of these models elsewhere, so if you’d like to read more you can check out Colin’s Personalization Content Model and Jeff’s Personalization Context Model

                        Campaign and Context cards: This level of the pyramid can help your team focus around the types of personalization to deliver end users and the use-cases in which they will experience it. User Segments

                        User segments can be created prescriptively or adaptively, based on user research (e.g. via rules and logic tied to set user behaviors or via A/B testing). At a minimum you will likely need to consider how to treat the unknown or first-time visitor, the guest or returning visitor for whom you may have a stateful cookie (or equivalent post-cookie identifier), or the authenticated visitor who is logged in. Here are some examples from the personalization pyramid:

                        • Unknown
                        • Guest
                        • Authenticated
                        • Default
                        • Referred
                        • Role
                        • Cohort
                        • Unique ID
                        Segment cards. Examples of common personalization segments: at a minimum, you will need to consider the anonymous, guest, and logged in user types. Segmentation can get dramatically more complex from there. Actionable Data

                        Every organization with any digital presence has data. It’s a matter of asking what data you can ethically collect on users, its inherent reliability and value, as to how can you use it (sometimes known as “data activation.”) Fortunately, the tide is turning to first-party data: a recent study by Twilio estimates some 80% of businesses are using at least some type of first-party data to personalize the customer experience. 

                        Source: “The State of Personalization 2021” by Twilio. Survey respondents were n=2,700 adult consumers who have purchased something online in the past 6 months, and n=300 adult manager+ decision-makers at consumer-facing companies that provide goods and/or services online. Respondents were from the United States, United Kingdom, Australia, and New Zealand.Data was collected from April 8 to April 20, 2021.

                        First-party data represents multiple advantages on the UX front, including being relatively simple to collect, more likely to be accurate, and less susceptible to the “creep factor” of third-party data. So a key part of your UX strategy should be to determine what the best form of data collection is on your audiences. Here are some examples:

                        Figure 1.1.2: Example of a personalization maturity curve, showing progression from basic recommendations functionality to true individualization. Credit: https://kibocommerce.com/blog/kibos-personalization-maturity-chart/

                        There is a progression of profiling when it comes to recognizing and making decisioning about different audiences and their signals. It tends to move towards more granular constructs about smaller and smaller cohorts of users as time and confidence and data volume grow.

                        While some combination of implicit / explicit data is generally a prerequisite for any implementation (more commonly referred to as first party and third-party data) ML efforts are typically not cost-effective directly out of the box. This is because a strong data backbone and content repository is a prerequisite for optimization. But these approaches should be considered as part of the larger roadmap and may indeed help accelerate the organization’s overall progress. Typically at this point you will partner with key stakeholders and product owners to design a profiling model. The profiling model includes defining approach to configuring profiles, profile keys, profile cards and pattern cards. A multi-faceted approach to profiling which makes it scalable.

                        Pulling it Together

                        While the cards comprise the starting point to an inventory of sorts (we provide blanks for you to tailor your own), a set of potential levers and motivations for the style of personalization activities you aspire to deliver, they are more valuable when thought of in a grouping. 

                        In assembling a card “hand”, one can begin to trace the entire trajectory from leadership focus down through a strategic and tactical execution. It is also at the heart of the way both co-authors have conducted workshops in assembling a program backlog—which is a fine subject for another article.

                        In the meantime, what is important to note is that each colored class of card is helpful to survey in understanding the range of choices potentially at your disposal, it is threading through and making concrete decisions about for whom this decisioning will be made: where, when, and how.

                        Scenario A: We want to use personalization to improve customer satisfaction on the website. For unknown users, we will create a short quiz to better identify what the user has come to do. This is sometimes referred to as “badging” a user in onboarding contexts, to better characterize their present intent and context. Lay Down Your Cards

                        Any sustainable personalization strategy must consider near, mid and long-term goals. Even with the leading CMS platforms like Sitecore and Adobe or the most exciting composable CMS DXP out there, there is simply no “easy button” wherein a personalization program can be stood up and immediately view meaningful results. That said, there is a common grammar to all personalization activities, just like every sentence has nouns and verbs. These cards attempt to map that territory.

                        Mobile-First CSS: Is It Time for a Rethink?

                          The mobile-first design methodology is great—it focuses on what really matters to the user, it’s well-practiced, and it’s been a common design pattern for years. So developing your CSS mobile-first should also be great, too…right? 

                          Well, not necessarily. Classic mobile-first CSS development is based on the principle of overwriting style declarations: you begin your CSS with default style declarations, and overwrite and/or add new styles as you add breakpoints with min-width media queries for larger viewports (for a good overview see “What is Mobile First CSS and Why Does It Rock?”). But all those exceptions create complexity and inefficiency, which in turn can lead to an increased testing effort and a code base that’s harder to maintain. Admit it—how many of us willingly want that?

                          On your own projects, mobile-first CSS may yet be the best tool for the job, but first you need to evaluate just how appropriate it is in light of the visual design and user interactions you’re working on. To help you get started, here’s how I go about tackling the factors you need to watch for, and I’ll discuss some alternate solutions if mobile-first doesn’t seem to suit your project.

                          Advantages of mobile-first

                          Some of the things to like with mobile-first CSS development—and why it’s been the de facto development methodology for so long—make a lot of sense:

                          Development hierarchy. One thing you undoubtedly get from mobile-first is a nice development hierarchy—you just focus on the mobile view and get developing. 

                          Tried and tested. It’s a tried and tested methodology that’s worked for years for a reason: it solves a problem really well.

                          Prioritizes the mobile view. The mobile view is the simplest and arguably the most important, as it encompasses all the key user journeys, and often accounts for a higher proportion of user visits (depending on the project). 

                          Prevents desktop-centric development. As development is done using desktop computers, it can be tempting to initially focus on the desktop view. But thinking about mobile from the start prevents us from getting stuck later on; no one wants to spend their time retrofitting a desktop-centric site to work on mobile devices!

                          Disadvantages of mobile-first

                          Setting style declarations and then overwriting them at higher breakpoints can lead to undesirable ramifications:

                          More complexity. The farther up the breakpoint hierarchy you go, the more unnecessary code you inherit from lower breakpoints. 

                          Higher CSS specificity. Styles that have been reverted to their browser default value in a class name declaration now have a higher specificity. This can be a headache on large projects when you want to keep the CSS selectors as simple as possible.

                          Requires more regression testing. Changes to the CSS at a lower view (like adding a new style) requires all higher breakpoints to be regression tested.

                          The browser can’t prioritize CSS downloads. At wider breakpoints, classic mobile-first min-width media queries don’t leverage the browser’s capability to download CSS files in priority order.

                          The problem of property value overrides

                          There is nothing inherently wrong with overwriting values; CSS was designed to do just that. Still, inheriting incorrect values is unhelpful and can be burdensome and inefficient. It can also lead to increased style specificity when you have to overwrite styles to reset them back to their defaults, something that may cause issues later on, especially if you are using a combination of bespoke CSS and utility classes. We won’t be able to use a utility class for a style that has been reset with a higher specificity.

                          With this in mind, I’m developing CSS with a focus on the default values much more these days. Since there’s no specific order, and no chains of specific values to keep track of, this frees me to develop breakpoints simultaneously. I concentrate on finding common styles and isolating the specific exceptions in closed media query ranges (that is, any range with a max-width set). 

                          This approach opens up some opportunities, as you can look at each breakpoint as a clean slate. If a component’s layout looks like it should be based on Flexbox at all breakpoints, it’s fine and can be coded in the default style sheet. But if it looks like Grid would be much better for large screens and Flexbox for mobile, these can both be done entirely independently when the CSS is put into closed media query ranges. Also, developing simultaneously requires you to have a good understanding of any given component in all breakpoints up front. This can help surface issues in the design earlier in the development process. We don’t want to get stuck down a rabbit hole building a complex component for mobile, and then get the designs for desktop and find they are equally complex and incompatible with the HTML we created for the mobile view! 

                          Though this approach isn’t going to suit everyone, I encourage you to give it a try. There are plenty of tools out there to help with concurrent development, such as Responsively App, Blisk, and many others. 

                          Having said that, I don’t feel the order itself is particularly relevant. If you are comfortable with focusing on the mobile view, have a good understanding of the requirements for other breakpoints, and prefer to work on one device at a time, then by all means stick with the classic development order. The important thing is to identify common styles and exceptions so you can put them in the relevant stylesheet—a sort of manual tree-shaking process! Personally, I find this a little easier when working on a component across breakpoints, but that’s by no means a requirement.

                          Closed media query ranges in practice 

                          In classic mobile-first CSS we overwrite the styles, but we can avoid this by using media query ranges. To illustrate the difference (I’m using SCSS for brevity), let’s assume there are three visual designs: 

                          • smaller than 768
                          • from 768 to below 1024
                          • 1024 and anything larger 

                          Take a simple example where a block-level element has a default padding of “20px,” which is overwritten at tablet to be “40px” and set back to “20px” on desktop.

                          Classic min-width mobile-first

                          .my-block {
                            padding: 20px;
                            @media (min-width: 768px) {
                              padding: 40px;
                            }
                            @media (min-width: 1024px) {
                              padding: 20px;
                            }
                          }

                          Closed media query range

                          .my-block {
                            padding: 20px;
                            @media (min-width: 768px) and (max-width: 1023.98px) {
                              padding: 40px;
                            }
                          }

                          The subtle difference is that the mobile-first example sets the default padding to “20px” and then overwrites it at each breakpoint, setting it three times in total. In contrast, the second example sets the default padding to “20px” and only overrides it at the relevant breakpoint where it isn’t the default value (in this instance, tablet is the exception).

                          The goal is to: 

                          • Only set styles when needed. 
                          • Not set them with the expectation of overwriting them later on, again and again. 

                          To this end, closed media query ranges are our best friend. If we need to make a change to any given view, we make it in the CSS media query range that applies to the specific breakpoint. We’ll be much less likely to introduce unwanted alterations, and our regression testing only needs to focus on the breakpoint we have actually edited. 

                          Taking the above example, if we find that .my-block spacing on desktop is already accounted for by the margin at that breakpoint, and since we want to remove the padding altogether, we could do this by setting the mobile padding in a closed media query range.

                          .my-block {
                            @media (max-width: 767.98px) {
                              padding: 20px;
                            }
                            @media (min-width: 768px) and (max-width: 1023.98px) {
                              padding: 40px;
                            }
                          }

                          The browser default padding for our block is “0,” so instead of adding a desktop media query and using unset or “0” for the padding value (which we would need with mobile-first), we can wrap the mobile padding in a closed media query (since it is now also an exception) so it won’t get picked up at wider breakpoints. At the desktop breakpoint, we won’t need to set any padding style, as we want the browser default value.

                          Bundling versus separating the CSS

                          Back in the day, keeping the number of requests to a minimum was very important due to the browser’s limit of concurrent requests (typically around six). As a consequence, the use of image sprites and CSS bundling was the norm, with all the CSS being downloaded in one go, as one stylesheet with highest priority. 

                          With HTTP/2 and HTTP/3 now on the scene, the number of requests is no longer the big deal it used to be. This allows us to separate the CSS into multiple files by media query. The clear benefit of this is the browser can now request the CSS it currently needs with a higher priority than the CSS it doesn’t. This is more performant and can reduce the overall time page rendering is blocked.

                          Which HTTP version are you using?

                          To determine which version of HTTP you’re using, go to your website and open your browser’s dev tools. Next, select the Network tab and make sure the Protocol column is visible. If “h2” is listed under Protocol, it means HTTP/2 is being used. 

                          Note: to view the Protocol in your browser’s dev tools, go to the Network tab, reload your page, right-click any column header (e.g., Name), and check the Protocol column.

                          Note: for a summarized comparison, see ImageKit’s “HTTP/2 vs. HTTP/1.”

                          Also, if your site is still using HTTP/1...WHY?!! What are you waiting for? There is excellent user support for HTTP/2.

                          Splitting the CSS

                          Separating the CSS into individual files is a worthwhile task. Linking the separate CSS files using the relevant media attribute allows the browser to identify which files are needed immediately (because they’re render-blocking) and which can be deferred. Based on this, it allocates each file an appropriate priority.

                          In the following example of a website visited on a mobile breakpoint, we can see the mobile and default CSS are loaded with “Highest” priority, as they are currently needed to render the page. The remaining CSS files (print, tablet, and desktop) are still downloaded in case they’ll be needed later, but with “Lowest” priority. 

                          With bundled CSS, the browser will have to download the CSS file and parse it before rendering can start.

                          While, as noted, with the CSS separated into different files linked and marked up with the relevant media attribute, the browser can prioritize the files it currently needs. Using closed media query ranges allows the browser to do this at all widths, as opposed to classic mobile-first min-width queries, where the desktop browser would have to download all the CSS with Highest priority. We can’t assume that desktop users always have a fast connection. For instance, in many rural areas, internet connection speeds are still slow. 

                          The media queries and number of separate CSS files will vary from project to project based on project requirements, but might look similar to the example below.

                          Bundled CSS

                          <link href="site.css" rel="stylesheet">

                          This single file contains all the CSS, including all media queries, and it will be downloaded with Highest priority.

                          Separated CSS

                          <link href="default.css" rel="stylesheet"><link href="mobile.css" media="screen and (max-width: 767.98px)" rel="stylesheet"><link href="tablet.css" media="screen and (min-width: 768px) and (max-width: 1083.98px)" rel="stylesheet"><link href="desktop.css" media="screen and (min-width: 1084px)" rel="stylesheet"><link href="print.css" media="print" rel="stylesheet">

                          Separating the CSS and specifying a media attribute value on each link tag allows the browser to prioritize what it currently needs. Out of the five files listed above, two will be downloaded with Highest priority: the default file, and the file that matches the current media query. The others will be downloaded with Lowest priority.

                          Depending on the project’s deployment strategy, a change to one file (mobile.css, for example) would only require the QA team to regression test on devices in that specific media query range. Compare that to the prospect of deploying the single bundled site.css file, an approach that would normally trigger a full regression test.

                          Moving on

                          The uptake of mobile-first CSS was a really important milestone in web development; it has helped front-end developers focus on mobile web applications, rather than developing sites on desktop and then attempting to retrofit them to work on other devices.

                          I don’t think anyone wants to return to that development model again, but it’s important we don’t lose sight of the issue it highlighted: that things can easily get convoluted and less efficient if we prioritize one particular device—any device—over others. For this reason, focusing on the CSS in its own right, always mindful of what is the default setting and what’s an exception, seems like the natural next step. I’ve started noticing small simplifications in my own CSS, as well as other developers’, and that testing and maintenance work is also a bit more simplified and productive. 

                          In general, simplifying CSS rule creation whenever we can is ultimately a cleaner approach than going around in circles of overrides. But whichever methodology you choose, it needs to suit the project. Mobile-first may—or may not—turn out to be the best choice for what’s involved, but first you need to solidly understand the trade-offs you’re stepping into.

                          Designers, (Re)define Success First

                            About two and a half years ago, I introduced the idea of daily ethical design. It was born out of my frustration with the many obstacles to achieving design that’s usable and equitable; protects people’s privacy, agency, and focus; benefits society; and restores nature. I argued that we need to overcome the inconveniences that prevent us from acting ethically and that we need to elevate design ethics to a more practical level by structurally integrating it into our daily work, processes, and tools.

                            Unfortunately, we’re still very far from this ideal. 

                            At the time, I didn’t know yet how to structurally integrate ethics. Yes, I had found some tools that had worked for me in previous projects, such as using checklists, assumption tracking, and “dark reality” sessions, but I didn’t manage to apply those in every project. I was still struggling for time and support, and at best I had only partially achieved a higher (moral) quality of design—which is far from my definition of structurally integrated.

                            I decided to dig deeper for the root causes in business that prevent us from practicing daily ethical design. Now, after much research and experimentation, I believe that I’ve found the key that will let us structurally integrate ethics. And it’s surprisingly simple! But first we need to zoom out to get a better understanding of what we’re up against.

                            Influence the system

                            Sadly, we’re trapped in a capitalistic system that reinforces consumerism and inequality, and it’s obsessed with the fantasy of endless growth. Sea levels, temperatures, and our demand for energy continue to rise unchallenged, while the gap between rich and poor continues to widen. Shareholders expect ever-higher returns on their investments, and companies feel forced to set short-term objectives that reflect this. Over the last decades, those objectives have twisted our well-intended human-centered mindset into a powerful machine that promotes ever-higher levels of consumption. When we’re working for an organization that pursues “double-digit growth” or “aggressive sales targets” (which is 99 percent of us), that’s very hard to resist while remaining human friendly. Even with our best intentions, and even though we like to say that we create solutions for people, we’re a part of the problem.

                            What can we do to change this?

                            We can start by acting on the right level of the system. Donella H. Meadows, a system thinker, once listed ways to influence a system in order of effectiveness. When you apply these to design, you get:

                            • At the lowest level of effectiveness, you can affect numbers such as usability scores or the number of design critiques. But none of that will change the direction of a company.
                            • Similarly, affecting buffers (such as team budgets), stocks (such as the number of designers), flows (such as the number of new hires), and delays (such as the time that it takes to hear about the effect of design) won’t significantly affect a company.
                            • Focusing instead on feedback loops such as management control, employee recognition, or design-system investments can help a company become better at achieving its objectives. But that doesn’t change the objectives themselves, which means that the organization will still work against your ethical-design ideals.
                            • The next level, information flows, is what most ethical-design initiatives focus on now: the exchange of ethical methods, toolkits, articles, conferences, workshops, and so on. This is also where ethical design has remained mostly theoretical. We’ve been focusing on the wrong level of the system all this time.
                            • Take rules, for example—they beat knowledge every time. There can be widely accepted rules, such as how finance works, or a scrum team’s definition of done. But ethical design can also be smothered by unofficial rules meant to maintain profits, often revealed through comments such as “the client didn’t ask for it” or “don’t make it too big.”
                            • Changing the rules without holding official power is very hard. That’s why the next level is so influential: self-organization. Experimentation, bottom-up initiatives, passion projects, self-steering teams—all of these are examples of self-organization that improve the resilience and creativity of a company. It’s exactly this diversity of viewpoints that’s needed to structurally tackle big systemic issues like consumerism, wealth inequality, and climate change.
                            • Yet even stronger than self-organization are objectives and metrics. Our companies want to make more money, which means that everything and everyone in the company does their best to… make the company more money. And once I realized that profit is nothing more than a measurement, I understood how crucial a very specific, defined metric can be toward pushing a company in a certain direction.

                            The takeaway? If we truly want to incorporate ethics into our daily design practice, we must first change the measurable objectives of the company we work for, from the bottom up.

                            Redefine success

                            Traditionally, we consider a product or service successful if it’s desirable to humans, technologically feasible, and financially viable. You tend to see these represented as equals; if you type the three words in a search engine, you’ll find diagrams of three equally sized, evenly arranged circles.

                            But in our hearts, we all know that the three dimensions aren’t equally weighted: it’s viability that ultimately controls whether a product will go live. So a more realistic representation might look like this:

                            Desirability and feasibility are the means; viability is the goal. Companies—outside of nonprofits and charities—exist to make money.

                            A genuinely purpose-driven company would try to reverse this dynamic: it would recognize finance for what it was intended for: a means. So both feasibility and viability are means to achieve what the company set out to achieve. It makes intuitive sense: to achieve most anything, you need resources, people, and money. (Fun fact: the Italian language knows no difference between feasibility and viability; both are simply fattibilità.)

                            But simply swapping viable for desirable isn’t enough to achieve an ethical outcome. Desirability is still linked to consumerism because the associated activities aim to identify what people want—whether it’s good for them or not. Desirability objectives, such as user satisfaction or conversion, don’t consider whether a product is healthy for people. They don’t prevent us from creating products that distract or manipulate people or stop us from contributing to society’s wealth inequality. They’re unsuitable for establishing a healthy balance with nature.

                            There’s a fourth dimension of success that’s missing: our designs also need to be ethical in the effect that they have on the world.

                            This is hardly a new idea. Many similar models exist, some calling the fourth dimension accountability, integrity, or responsibility. What I’ve never seen before, however, is the necessary step that comes after: to influence the system as designers and to make ethical design more practical, we must create objectives for ethical design that are achievable and inspirational. There’s no one way to do this because it highly depends on your culture, values, and industry. But I’ll give you the version that I developed with a group of colleagues at a design agency. Consider it a template to get started.

                            Pursue well-being, equity, and sustainability

                            We created objectives that address design’s effect on three levels: individual, societal, and global.

                            An objective on the individual level tells us what success is beyond the typical focus of usability and satisfaction—instead considering matters such as how much time and attention is required from users. We pursued well-being:

                            We create products and services that allow for people’s health and happiness. Our solutions are calm, transparent, nonaddictive, and nonmisleading. We respect our users’ time, attention, and privacy, and help them make healthy and respectful choices.

                            An objective on the societal level forces us to consider our impact beyond just the user, widening our attention to the economy, communities, and other indirect stakeholders. We called this objective equity:

                            We create products and services that have a positive social impact. We consider economic equality, racial justice, and the inclusivity and diversity of people as teams, users, and customer segments. We listen to local culture, communities, and those we affect.

                            Finally, the objective on the global level aims to ensure that we remain in balance with the only home we have as humanity. Referring to it simply as sustainability, our definition was:

                            We create products and services that reward sufficiency and reusability. Our solutions support the circular economy: we create value from waste, repurpose products, and prioritize sustainable choices. We deliver functionality instead of ownership, and we limit energy use.

                            In short, ethical design (to us) meant achieving wellbeing for each user and an equitable value distribution within society through a design that can be sustained by our living planet. When we introduced these objectives in the company, for many colleagues, design ethics and responsible design suddenly became tangible and achievable through practical—and even familiar—actions.

                            Measure impact 

                            But defining these objectives still isn’t enough. What truly caught the attention of senior management was the fact that we created a way to measure every design project’s well-being, equity, and sustainability.

                            This overview lists example metrics that you can use as you pursue well-being, equity, and sustainability:

                            There’s a lot of power in measurement. As the saying goes, what gets measured gets done. Donella Meadows once shared this example:

                            “If the desired system state is national security, and that is defined as the amount of money spent on the military, the system will produce military spending. It may or may not produce national security.”

                            This phenomenon explains why desirability is a poor indicator of success: it’s typically defined as the increase in customer satisfaction, session length, frequency of use, conversion rate, churn rate, download rate, and so on. But none of these metrics increase the health of people, communities, or ecosystems. What if instead we measured success through metrics for (digital) well-being, such as (reduced) screen time or software energy consumption?

                            There’s another important message here. Even if we set an objective to build a calm interface, if we were to choose the wrong metric for calmness—say, the number of interface elements—we could still end up with a screen that induces anxiety. Choosing the wrong metric can completely undo good intentions. 

                            Additionally, choosing the right metric is enormously helpful in focusing the design team. Once you go through the exercise of choosing metrics for our objectives, you’re forced to consider what success looks like concretely and how you can prove that you’ve reached your ethical objectives. It also forces you to consider what we as designers have control over: what can I include in my design or change in my process that will lead to the right type of success? The answer to this question brings a lot of clarity and focus.

                            And finally, it’s good to remember that traditional businesses run on measurements, and managers love to spend much time discussing charts (ideally hockey-stick shaped)—especially if they concern profit, the one-above-all of metrics. For good or ill, to improve the system, to have a serious discussion about ethical design with managers, we’ll need to speak that business language.

                            Practice daily ethical design

                            Once you’ve defined your objectives and you have a reasonable idea of the potential metrics for your design project, only then do you have a chance to structurally practice ethical design. It “simply” becomes a matter of using your creativity and choosing from all the knowledge and toolkits already available to you.

                            I think this is quite exciting! It opens a whole new set of challenges and considerations for the design process. Should you go with that energy-consuming video or would a simple illustration be enough? Which typeface is the most calm and inclusive? Which new tools and methods do you use? When is the website’s end of life? How can you provide the same service while requiring less attention from users? How do you make sure that those who are affected by decisions are there when those decisions are made? How can you measure our effects?

                            The redefinition of success will completely change what it means to do good design.

                            There is, however, a final piece of the puzzle that’s missing: convincing your client, product owner, or manager to be mindful of well-being, equity, and sustainability. For this, it’s essential to engage stakeholders in a dedicated kickoff session.

                            Kick it off or fall back to status quo

                            The kickoff is the most important meeting that can be so easy to forget to include. It consists of two major phases: 1) the alignment of expectations, and 2) the definition of success.

                            In the first phase, the entire (design) team goes over the project brief and meets with all the relevant stakeholders. Everyone gets to know one another and express their expectations on the outcome and their contributions to achieving it. Assumptions are raised and discussed. The aim is to get on the same level of understanding and to in turn avoid preventable miscommunications and surprises later in the project.

                            For example, for a recent freelance project that aimed to design a digital platform that facilitates US student advisors’ documentation and communication, we conducted an online kickoff with the client, a subject-matter expert, and two other designers. We used a combination of canvases on Miro: one with questions from “Manual of Me” (to get to know each other), a Team Canvas (to express expectations), and a version of the Project Canvas to align on scope, timeline, and other practical matters.

                            The above is the traditional purpose of a kickoff. But just as important as expressing expectations is agreeing on what success means for the project—in terms of desirability, viability, feasibility, and ethics. What are the objectives in each dimension?

                            Agreement on what success means at such an early stage is crucial because you can rely on it for the remainder of the project. If, for example, the design team wants to build an inclusive app for a diverse user group, they can raise diversity as a specific success criterion during the kickoff. If the client agrees, the team can refer back to that promise throughout the project. “As we agreed in our first meeting, having a diverse user group that includes A and B is necessary to build a successful product. So we do activity X and follow research process Y.” Compare those odds to a situation in which the team didn’t agree to that beforehand and had to ask for permission halfway through the project. The client might argue that that came on top of the agreed scope—and she’d be right.

                            In the case of this freelance project, to define success I prepared a round canvas that I call the Wheel of Success. It consists of an inner ring, meant to capture ideas for objectives, and a set of outer rings, meant to capture ideas on how to measure those objectives. The rings are divided into five dimensions of successful design: healthy, equitable, sustainable, desirable, feasible, and viable.

                            We went through each dimension, writing down ideas on digital sticky notes. Then we discussed our ideas and verbally agreed on the most important ones. For example, our client agreed that sustainability and progressive enhancement are important success criteria for the platform. And the subject-matter expert emphasized the importance of including students from low-income and disadvantaged groups in the design process.

                            After the kickoff, we summarized our ideas and shared understanding in a project brief that captured these aspects:

                            • the project’s origin and purpose: why are we doing this project?
                            • the problem definition: what do we want to solve?
                            • the concrete goals and metrics for each success dimension: what do we want to achieve?
                            • the scope, process, and role descriptions: how will we achieve it?

                            With such a brief in place, you can use the agreed-upon objectives and concrete metrics as a checklist of success, and your design team will be ready to pursue the right objective—using the tools, methods, and metrics at their disposal to achieve ethical outcomes.

                            Conclusion

                            Over the past year, quite a few colleagues have asked me, “Where do I start with ethical design?” My answer has always been the same: organize a session with your stakeholders to (re)define success. Even though you might not always be 100 percent successful in agreeing on goals that cover all responsibility objectives, that beats the alternative (the status quo) every time. If you want to be an ethical, responsible designer, there’s no skipping this step.

                            To be even more specific: if you consider yourself a strategic designer, your challenge is to define ethical objectives, set the right metrics, and conduct those kick-off sessions. If you consider yourself a system designer, your starting point is to understand how your industry contributes to consumerism and inequality, understand how finance drives business, and brainstorm which levers are available to influence the system on the highest level. Then redefine success to create the space to exercise those levers.

                            And for those who consider themselves service designers or UX designers or UI designers: if you truly want to have a positive, meaningful impact, stay away from the toolkits and meetups and conferences for a while. Instead, gather your colleagues and define goals for well-being, equity, and sustainability through design. Engage your stakeholders in a workshop and challenge them to think of ways to achieve and measure those ethical goals. Take their input, make it concrete and visible, ask for their agreement, and hold them to it.

                            Otherwise, I’m genuinely sorry to say, you’re wasting your precious time and creative energy.

                            Of course, engaging your stakeholders in this way can be uncomfortable. Many of my colleagues expressed doubts such as “What will the client think of this?,” “Will they take me seriously?,” and “Can’t we just do it within the design team instead?” In fact, a product manager once asked me why ethics couldn’t just be a structured part of the design process—to just do it without spending the effort to define ethical objectives. It’s a tempting idea, right? We wouldn’t have to have difficult discussions with stakeholders about what values or which key-performance indicators to pursue. It would let us focus on what we like and do best: designing.

                            But as systems theory tells us, that’s not enough. For those of us who aren’t from marginalized groups and have the privilege to be able to speak up and be heard, that uncomfortable space is exactly where we need to be if we truly want to make a difference. We can’t remain within the design-for-designers bubble, enjoying our privileged working-from-home situation, disconnected from the real world out there. For those of us who have the possibility to speak up and be heard: if we solely keep talking about ethical design and it remains at the level of articles and toolkits—we’re not designing ethically. It’s just theory. We need to actively engage our colleagues and clients by challenging them to redefine success in business.

                            With a bit of courage, determination, and focus, we can break out of this cage that finance and business-as-usual have built around us and become facilitators of a new type of business that can see beyond financial value. We just need to agree on the right objectives at the start of each design project, find the right metrics, and realize that we already have everything that we need to get started. That’s what it means to do daily ethical design.

                            For their inspiration and support over the years, I would like to thank Emanuela Cozzi Schettini, José Gallegos, Annegret Bönemann, Ian Dorr, Vera Rademaker, Virginia Rispoli, Cecilia Scolaro, Rouzbeh Amini, and many others.

                            Breaking Out of the Box

                              CSS is about styling boxes. In fact, the whole web is made of boxes, from the browser viewport to elements on a page. But every once in a while a new feature comes along that makes us rethink our design approach.

                              Round displays, for example, make it fun to play with circular clip areas. Mobile screen notches and virtual keyboards offer challenges to best organize content that stays clear of them. And dual screen or foldable devices make us rethink how to best use available space in a number of different device postures.

                              Sketches of a round display, a common rectangular mobile display, and a device with a foldable display.

                              These recent evolutions of the web platform made it both more challenging and more interesting to design products. They’re great opportunities for us to break out of our rectangular boxes.

                              I’d like to talk about a new feature similar to the above: the Window Controls Overlay for Progressive Web Apps (PWAs).

                              Progressive Web Apps are blurring the lines between apps and websites. They combine the best of both worlds. On one hand, they’re stable, linkable, searchable, and responsive just like websites. On the other hand, they provide additional powerful capabilities, work offline, and read files just like native apps.

                              As a design surface, PWAs are really interesting because they challenge us to think about what mixing web and device-native user interfaces can be. On desktop devices in particular, we have more than 40 years of history telling us what applications should look like, and it can be hard to break out of this mental model.

                              At the end of the day though, PWAs on desktop are constrained to the window they appear in: a rectangle with a title bar at the top.

                              Here’s what a typical desktop PWA app looks like:

                              Sketches of two rectangular user interfaces representing the desktop Progressive Web App status quo on the macOS and Windows operating systems, respectively. 

                              Sure, as the author of a PWA, you get to choose the color of the title bar (using the Web Application Manifest theme_color property), but that’s about it.

                              What if we could think outside this box, and reclaim the real estate of the app’s entire window? Doing so would give us a chance to make our apps more beautiful and feel more integrated in the operating system.

                              This is exactly what the Window Controls Overlay offers. This new PWA functionality makes it possible to take advantage of the full surface area of the app, including where the title bar normally appears.

                              About the title bar and window controls

                              Let’s start with an explanation of what the title bar and window controls are.

                              The title bar is the area displayed at the top of an app window, which usually contains the app’s name. Window controls are the affordances, or buttons, that make it possible to minimize, maximize, or close the app’s window, and are also displayed at the top.

                              A sketch of a rectangular application user interface highlighting the title bar area and window control buttons.

                              Window Controls Overlay removes the physical constraint of the title bar and window controls areas. It frees up the full height of the app window, enabling the title bar and window control buttons to be overlaid on top of the application’s web content. 

                              A sketch of a rectangular application user interface using Window Controls Overlay. The title bar and window controls are no longer in an area separated from the app’s content.

                              If you are reading this article on a desktop computer, take a quick look at other apps. Chances are they’re already doing something similar to this. In fact, the very web browser you are using to read this uses the top area to display tabs.

                              A screenshot of the top area of a browser’s user interface showing a group of tabs that share the same horizontal space as the app window controls.

                              Spotify displays album artwork all the way to the top edge of the application window.

                              A screenshot of an album in Spotify’s desktop application. Album artwork spans the entire width of the main content area, all the way to the top and right edges of the window, and the right edge of the main navigation area on the left side. The application and album navigation controls are overlaid directly on top of the album artwork.

                              Microsoft Word uses the available title bar space to display the auto-save and search functionalities, and more.

                              A screenshot of Microsoft Word’s toolbar interface. Document file information, search, and other functionality appear at the top of the window, sharing the same horizontal space as the app’s window controls.

                              The whole point of this feature is to allow you to make use of this space with your own content while providing a way to account for the window control buttons. And it enables you to offer this modified experience on a range of platforms while not adversely affecting the experience on browsers or devices that don’t support Window Controls Overlay. After all, PWAs are all about progressive enhancement, so this feature is a chance to enhance your app to use this extra space when it’s available.

                              Let’s use the feature

                              For the rest of this article, we’ll be working on a demo app to learn more about using the feature.

                              The demo app is called 1DIV. It’s a simple CSS playground where users can create designs using CSS and a single HTML element.

                              The app has two pages. The first lists the existing CSS designs you’ve created:

                              A screenshot of the 1DIV app displaying a thumbnail grid of CSS designs a user created.

                              The second page enables you to create and edit CSS designs:

                              A screenshot of the 1DIV app editor page. The top half of the window displays a rendered CSS design, and a text editor on the bottom half of the window displays the CSS used to create it.

                              Since I’ve added a simple web manifest and service worker, we can install the app as a PWA on desktop. Here is what it looks like on macOS:

                              Screenshots of the 1DIV app thumbnail view and CSS editor view on macOS. This version of the app’s window has a separate control bar at the top for the app name and window control buttons.

                              And on Windows:

                              Screenshots of the 1DIV app thumbnail view and CSS editor view on the Windows operating system. This version of the app’s window also has a separate control bar at the top for the app name and window control buttons.

                              Our app is looking good, but the white title bar in the first page is wasted space. In the second page, it would be really nice if the design area went all the way to the top of the app window.

                              Let’s use the Window Controls Overlay feature to improve this.

                              Enabling Window Controls Overlay

                              The feature is still experimental at the moment. To try it, you need to enable it in one of the supported browsers.

                              As of now, it has been implemented in Chromium, as a collaboration between Microsoft and Google. We can therefore use it in Chrome or Edge by going to the internal about://flags page, and enabling the Desktop PWA Window Controls Overlay flag.

                              Using Window Controls Overlay

                              To use the feature, we need to add the following display_override member to our web app’s manifest file:

                              {
                                "name": "1DIV",
                                "description": "1DIV is a mini CSS playground",
                                "lang": "en-US",
                                "start_url": "/",
                                "theme_color": "#ffffff",
                                "background_color": "#ffffff",
                                "display_override": [
                                  "window-controls-overlay"
                                ],
                                "icons": [
                                  ...
                                ]
                              }
                              

                              On the surface, the feature is really simple to use. This manifest change is the only thing we need to make the title bar disappear and turn the window controls into an overlay.

                              However, to provide a great experience for all users regardless of what device or browser they use, and to make the most of the title bar area in our design, we’ll need a bit of CSS and JavaScript code.

                              Here is what the app looks like now:

                              Screenshot of the 1DIV app thumbnail view using Window Controls Overlay on macOS. The separate top bar area is gone, but the window controls are now blocking some of the app’s interface

                              The title bar is gone, which is what we wanted, but our logo, search field, and NEW button are partially covered by the window controls because now our layout starts at the top of the window.

                              It’s similar on Windows, with the difference that the close, maximize, and minimize buttons appear on the right side, grouped together with the PWA control buttons:

                              Screenshot of the 1DIV app thumbnail display using Window Controls Overlay on the Windows operating system. The separate top bar area is gone, but the window controls are now blocking some of the app’s content. Using CSS to keep clear of the window controls

                              Along with the feature, new CSS environment variables have been introduced:

                              • titlebar-area-x
                              • titlebar-area-y
                              • titlebar-area-width
                              • titlebar-area-height

                              You use these variables with the CSS env() function to position your content where the title bar would have been while ensuring it won’t overlap with the window controls. In our case, we’ll use two of the variables to position our header, which contains the logo, search bar, and NEW button. 

                              header {
                                position: absolute;
                                left: env(titlebar-area-x, 0);
                                width: env(titlebar-area-width, 100%);
                                height: var(--toolbar-height);
                              }
                              

                              The titlebar-area-x variable gives us the distance from the left of the viewport to where the title bar would appear, and titlebar-area-width is its width. (Remember, this is not equivalent to the width of the entire viewport, just the title bar portion, which as noted earlier, doesn’t include the window controls.)

                              By doing this, we make sure our content remains fully visible. We’re also defining fallback values (the second parameter in the env() function) for when the variables are not defined (such as on non-supporting browsers, or when the Windows Control Overlay feature is disabled).

                              Screenshot of the 1DIV app thumbnail view on macOS with Window Controls Overlay and our CSS updated. The app content that the window controls had been blocking has been repositioned. Screenshot of the 1DIV app thumbnail view on the Windows operating system with Window Controls Overlay and our updated CSS. The app content that the window controls had been blocking has been repositioned.

                              Now our header adapts to its surroundings, and it doesn’t feel like the window control buttons have been added as an afterthought. The app looks a lot more like a native app.

                              Changing the window controls background color so it blends in

                              Now let’s take a closer look at our second page: the CSS playground editor.

                              Screenshots of the 1DIV app CSS editor view with Window Controls Overlay in macOS and Windows, respectively. The window controls overlay areas have a solid white background color, which contrasts with the hot pink color of the example CSS design displayed in the editor.

                              Not great. Our CSS demo area does go all the way to the top, which is what we wanted, but the way the window controls appear as white rectangles on top of it is quite jarring.

                              We can fix this by changing the app’s theme color. There are a couple of ways to define it:

                              • PWAs can define a theme color in the web app manifest file using the theme_color manifest member. This color is then used by the OS in different ways. On desktop platforms, it is used to provide a background color to the title bar and window controls.
                              • Websites can use the theme-color meta tag as well. It’s used by browsers to customize the color of the UI around the web page. For PWAs, this color can override the manifest theme_color.

                              In our case, we can set the manifest theme_color to white to provide the right default color for our app. The OS will read this color value when the app is installed and use it to make the window controls background color white. This color works great for our main page with the list of demos.

                              The theme-color meta tag can be changed at runtime, using JavaScript. So we can do that to override the white with the right demo background color when one is opened.

                              Here is the function we’ll use:

                              function themeWindow(bgColor) {
                                document.querySelector("meta[name=theme-color]").setAttribute('content', bgColor);
                              }

                              With this in place, we can imagine how using color and CSS transitions can produce a smooth change from the list page to the demo page, and enable the window control buttons to blend in with the rest of the app’s interface.

                              Screenshot of the 1DIV app CSS editor view on the Windows operating system with Window Controls Overlay and updated CSS demonstrating how the window control buttons blend in with the rest of the app’s interface. Dragging the window

                              Now, getting rid of the title bar entirely does have an important accessibility consequence: it’s much more difficult to move the application window around.

                              The title bar provides a sizable area for users to click and drag, but by using the Window Controls Overlay feature, this area becomes limited to where the control buttons are, and users have to very precisely aim between these buttons to move the window.

                              Fortunately, this can be fixed using CSS with the app-region property. This property is, for now, only supported in Chromium-based browsers and needs the -webkit- vendor prefix. 

                              To make any element of the app become a dragging target for the window, we can use the following: 

                              -webkit-app-region: drag;

                              It is also possible to explicitly make an element non-draggable: 

                              -webkit-app-region: no-drag; 

                              These options can be useful for us. We can make the entire header a dragging target, but make the search field and NEW button within it non-draggable so they can still be used as normal.

                              However, because the editor page doesn’t display the header, users wouldn’t be able to drag the window while editing code. So let's use a different approach. We’ll create another element before our header, also absolutely positioned, and dedicated to dragging the window.

                              <div class="drag"></div>
                              <header>...</header>
                              .drag {
                                position: absolute;
                                top: 0;
                                width: 100%;
                                height: env(titlebar-area-height, 0);
                                -webkit-app-region: drag;
                              }

                              With the above code, we’re making the draggable area span the entire viewport width, and using the titlebar-area-height variable to make it as tall as what the title bar would have been. This way, our draggable area is aligned with the window control buttons as shown below.

                              And, now, to make sure our search field and button remain usable:

                              header .search,
                              header .new {
                                -webkit-app-region: no-drag;
                              }

                              With the above code, users can click and drag where the title bar used to be. It is an area that users expect to be able to use to move windows on desktop, and we’re not breaking this expectation, which is good.

                              An animated view of the 1DIV app being dragged across a Windows desktop with the mouse. Adapting to window resize

                              It may be useful for an app to know both whether the window controls overlay is visible and when its size changes. In our case, if the user made the window very narrow, there wouldn’t be enough space for the search field, logo, and button to fit, so we’d want to push them down a bit.

                              The Window Controls Overlay feature comes with a JavaScript API we can use to do this: navigator.windowControlsOverlay.

                              The API provides three interesting things:

                              • navigator.windowControlsOverlay.visible lets us know whether the overlay is visible.
                              • navigator.windowControlsOverlay.getBoundingClientRect() lets us know the position and size of the title bar area.
                              • navigator.windowControlsOverlay.ongeometrychange lets us know when the size or visibility changes.

                              Let’s use this to be aware of the size of the title bar area and move the header down if it’s too narrow.

                              if (navigator.windowControlsOverlay) {
                                navigator.windowControlsOverlay.addEventListener('geometrychange', () => {
                                  const { width } = navigator.windowControlsOverlay.getBoundingClientRect();
                                  document.body.classList.toggle('narrow', width < 250);
                                });
                              }

                              In the example above, we set the narrow class on the body of the app if the title bar area is narrower than 250px. We could do something similar with a media query, but using the windowControlsOverlay API has two advantages for our use case:

                              • It’s only fired when the feature is supported and used; we don’t want to adapt the design otherwise.
                              • We get the size of the title bar area across operating systems, which is great because the size of the window controls is different on Mac and Windows. Using a media query wouldn’t make it possible for us to know exactly how much space remains.
                              .narrow header {
                                top: env(titlebar-area-height, 0);
                                left: 0;
                                width: 100%;
                              }

                              Using the above CSS code, we can move our header down to stay clear of the window control buttons when the window is too narrow, and move the thumbnails down accordingly.

                              A screenshot of the 1DIV app on Windows showing the app’s content adjusted for a much narrower viewport. Thirty pixels of exciting design opportunities


                              Using the Window Controls Overlay feature, we were able to take our simple demo app and turn it into something that feels so much more integrated on desktop devices. Something that reaches out of the usual window constraints and provides a custom experience for its users.

                              In reality, this feature only gives us about 30 pixels of extra room and comes with challenges on how to deal with the window controls. And yet, this extra room and those challenges can be turned into exciting design opportunities.

                              More devices of all shapes and forms get invented all the time, and the web keeps on evolving to adapt to them. New features get added to the web platform to allow us, web authors, to integrate more and more deeply with those devices. From watches or foldable devices to desktop computers, we need to evolve our design approach for the web. Building for the web now lets us think outside the rectangular box.

                              So let’s embrace this. Let’s use the standard technologies already at our disposal, and experiment with new ideas to provide tailored experiences for all devices, all from a single codebase!


                              If you get a chance to try the Window Controls Overlay feature and have feedback about it, you can open issues on the spec’s repository. It’s still early in the development of this feature, and you can help make it even better. Or, you can take a look at the feature’s existing documentation, or this demo app and its source code

                              How to Sell UX Research with Two Simple Questions

                                Do you find yourself designing screens with only a vague idea of how the things on the screen relate to the things elsewhere in the system? Do you leave stakeholder meetings with unclear directives that often seem to contradict previous conversations? You know a better understanding of user needs would help the team get clear on what you are actually trying to accomplish, but time and budget for research is tight. When it comes to asking for more direct contact with your users, you might feel like poor Oliver Twist, timidly asking, “Please, sir, I want some more.” 

                                Here’s the trick. You need to get stakeholders themselves to identify high-risk assumptions and hidden complexity, so that they become just as motivated as you to get answers from users. Basically, you need to make them think it’s their idea. 

                                In this article, I’ll show you how to collaboratively expose misalignment and gaps in the team’s shared understanding by bringing the team together around two simple questions:

                                1. What are the objects?
                                2. What are the relationships between those objects?
                                A gauntlet between research and screen design

                                These two questions align to the first two steps of the ORCA process, which might become your new best friend when it comes to reducing guesswork. Wait, what’s ORCA?! Glad you asked.

                                ORCA stands for Objects, Relationships, CTAs, and Attributes, and it outlines a process for creating solid object-oriented user experiences. Object-oriented UX is my design philosophy. ORCA is an iterative methodology for synthesizing user research into an elegant structural foundation to support screen and interaction design. OOUX and ORCA have made my work as a UX designer more collaborative, effective, efficient, fun, strategic, and meaningful.

                                The ORCA process has four iterative rounds and a whopping fifteen steps. In each round we get more clarity on our Os, Rs, Cs, and As.

                                The four rounds and fifteen steps of the ORCA process. In the OOUX world, we love color-coding. Blue is reserved for objects! (Yellow is for core content, pink is for metadata, and green is for calls-to-action. Learn more about the color-coded object map and connecting CTAs to objects.)

                                I sometimes say that ORCA is a “garbage in, garbage out” process. To ensure that the testable prototype produced in the final round actually tests well, the process needs to be fed by good research. But if you don’t have a ton of research, the beginning of the ORCA process serves another purpose: it helps you sell the need for research.

                                ORCA strengthens the weak spot between research and design by helping distill research into solid information architecture—scaffolding for the screen design and interaction design to hang on.

                                In other words, the ORCA process serves as a gauntlet between research and design. With good research, you can gracefully ride the killer whale from research into design. But without good research, the process effectively spits you back into research and with a cache of specific open questions.

                                Getting in the same curiosity-boat

                                What gets us into trouble is not what we don’t know. It’s what we know for sure that just ain’t so.

                                Mark Twain

                                The first two steps of the ORCA process—Object Discovery and Relationship Discovery—shine a spotlight on the dark, dusty corners of your team’s misalignments and any inherent complexity that’s been swept under the rug. It begins to expose what this classic comic so beautifully illustrates:

                                The original “Tree Swing Project Management” cartoon dates back to the 1960s or 1970s and has no artist attribution we could find.

                                This is one reason why so many UX designers are frustrated in their job and why many projects fail. And this is also why we often can’t sell research: every decision-maker is confident in their own mental picture. 

                                Once we expose hidden fuzzy patches in each picture and the differences between them all, the case for user research makes itself.

                                But how we do this is important. However much we might want to, we can’t just tell everyone, “YOU ARE WRONG!” Instead, we need to facilitate and guide our team members to self-identify holes in their picture. When stakeholders take ownership of assumptions and gaps in understanding, BAM! Suddenly, UX research is not such a hard sell, and everyone is aboard the same curiosity-boat.

                                Say your users are doctors. And you have no idea how doctors use the system you are tasked with redesigning.

                                You might try to sell research by honestly saying: “We need to understand doctors better! What are their pain points? How do they use the current app?” But here’s the problem with that. Those questions are vague, and the answers to them don’t feel acutely actionable.

                                Instead, you want your stakeholders themselves to ask super-specific questions. This is more like the kind of conversation you need to facilitate. Let’s listen in:

                                “Wait a sec, how often do doctors share patients? Does a patient in this system have primary and secondary doctors?”

                                “Can a patient even have more than one primary doctor?”

                                “Is it a ‘primary doctor’ or just a ‘primary caregiver’… Can’t that role be a nurse practitioner?”

                                “No, caregivers are something else… That’s the patient’s family contacts, right?”

                                “So are caregivers in scope for this redesign?”

                                “Yeah, because if a caregiver is present at an appointment, the doctor needs to note that. Like, tag the caregiver on the note… Or on the appointment?”

                                Now we are getting somewhere. Do you see how powerful it can be getting stakeholders to debate these questions themselves? The diabolical goal here is to shake their confidence—gently and diplomatically.

                                When these kinds of questions bubble up collaboratively and come directly from the mouths of your stakeholders and decision-makers, suddenly, designing screens without knowing the answers to these questions seems incredibly risky, even silly.

                                If we create software without understanding the real-world information environment of our users, we will likely create software that does not align to the real-world information environment of our users. And this will, hands down, result in a more confusing, more complex, and less intuitive software product.

                                The two questions

                                But how do we get to these kinds of meaty questions diplomatically, efficiently, collaboratively, and reliably

                                We can do this by starting with those two big questions that align to the first two steps of the ORCA process:

                                1. What are the objects?
                                2. What are the relationships between those objects?

                                In practice, getting to these answers is easier said than done. I’m going to show you how these two simple questions can provide the outline for an Object Definition Workshop. During this workshop, these “seed” questions will blossom into dozens of specific questions and shine a spotlight on the need for more user research.

                                Prep work: Noun foraging

                                In the next section, I’ll show you how to run an Object Definition Workshop with your stakeholders (and entire cross-functional team, hopefully). But first, you need to do some prep work.

                                Basically, look for nouns that are particular to the business or industry of your project, and do it across at least a few sources. I call this noun foraging.

                                Here are just a few great noun foraging sources:

                                • the product’s marketing site
                                • the product’s competitors’ marketing sites (competitive analysis, anyone?)
                                • the existing product (look at labels!)
                                • user interview transcripts
                                • notes from stakeholder interviews or vision docs from stakeholders

                                Put your detective hat on, my dear Watson. Get resourceful and leverage what you have. If all you have is a marketing website, some screenshots of the existing legacy system, and access to customer service chat logs, then use those.

                                As you peruse these sources, watch for the nouns that are used over and over again, and start listing them (preferably on blue sticky notes if you’ll be creating an object map later!).

                                You’ll want to focus on nouns that might represent objects in your system. If you are having trouble determining if a noun might be object-worthy, remember the acronym SIP and test for:

                                1. Structure
                                2. Instances
                                3. Purpose

                                Think of a library app, for example. Is “book” an object?

                                Structure: can you think of a few attributes for this potential object? Title, author, publish date… Yep, it has structure. Check!

                                Instance: what are some examples of this potential “book” object? Can you name a few? The Alchemist, Ready Player One, Everybody Poops… OK, check!

                                Purpose: why is this object important to the users and business? Well, “book” is what our library client is providing to people and books are why people come to the library… Check, check, check!

                                SIP: Structure, Instances, and Purpose! (Here’s a flowchart where I elaborate even more on SIP.)

                                As you are noun foraging, focus on capturing the nouns that have SIP. Avoid capturing components like dropdowns, checkboxes, and calendar pickers—your UX system is not your design system! Components are just the packaging for objects—they are a means to an end. No one is coming to your digital place to play with your dropdown! They are coming for the VALUABLE THINGS and what they can do with them. Those things, or objects, are what we are trying to identify.

                                Let’s say we work for a startup disrupting the email experience. This is how I’d start my noun foraging.

                                First I’d look at my own email client, which happens to be Gmail. I’d then look at Outlook and the new HEY email. I’d look at Yahoo, Hotmail…I’d even look at Slack and Basecamp and other so-called “email replacers.” I’d read some articles, reviews, and forum threads where people are complaining about email. While doing all this, I would look for and write down the nouns.

                                (Before moving on, feel free to go noun foraging for this hypothetical product, too, and then scroll down to see how much our lists match up. Just don’t get lost in your own emails! Come back to me!)

                                Drumroll, please…

                                Here are a few nouns I came up with during my noun foraging:

                                • email message
                                • thread
                                • contact
                                • client
                                • rule/automation
                                • email address that is not a contact?
                                • contact groups
                                • attachment
                                • Google doc file / other integrated file
                                • newsletter? (HEY treats this differently)
                                • saved responses and templates
                                In the OOUX world, we love color-coding. Blue is reserved for objects! (Yellow is for core content, pink is for metadata, and green is for calls-to-action. Learn more about the color coded object map and connecting CTAs to objects.)

                                Scan your list of nouns and pick out words that you are completely clueless about. In our email example, it might be client or automation. Do as much homework as you can before your session with stakeholders: google what’s googleable. But other terms might be so specific to the product or domain that you need to have a conversation about them.

                                Aside: here are some real nouns foraged during my own past project work that I needed my stakeholders to help me understand:

                                • Record Locator
                                • Incentive Home
                                • Augmented Line Item
                                • Curriculum-Based Measurement Probe

                                This is really all you need to prepare for the workshop session: a list of nouns that represent potential objects and a short list of nouns that need to be defined further.

                                Facilitate an Object Definition Workshop

                                You could actually start your workshop with noun foraging—this activity can be done collaboratively. If you have five people in the room, pick five sources, assign one to every person, and give everyone ten minutes to find the objects within their source. When the time’s up, come together and find the overlap. Affinity mapping is your friend here!

                                If your team is short on time and might be reluctant to do this kind of grunt work (which is usually the case) do your own noun foraging beforehand, but be prepared to show your work. I love presenting screenshots of documents and screens with all the nouns already highlighted. Bring the artifacts of your process, and start the workshop with a five-minute overview of your noun foraging journey.

                                HOT TIP: before jumping into the workshop, frame the conversation as a requirements-gathering session to help you better understand the scope and details of the system. You don’t need to let them know that you’re looking for gaps in the team’s understanding so that you can prove the need for more user research—that will be our little secret. Instead, go into the session optimistically, as if your knowledgeable stakeholders and PMs and biz folks already have all the answers. 

                                Then, let the question whack-a-mole commence.

                                1. What is this thing?

                                Want to have some real fun? At the beginning of your session, ask stakeholders to privately write definitions for the handful of obscure nouns you might be uncertain about. Then, have everyone show their cards at the same time and see if you get different definitions (you will). This is gold for exposing misalignment and starting great conversations.

                                As your discussion unfolds, capture any agreed-upon definitions. And when uncertainty emerges, quietly (but visibly) start an “open questions” parking lot. 😉

                                After definitions solidify, here’s a great follow-up:

                                2. Do our users know what these things are? What do users call this thing?

                                Stakeholder 1: They probably call email clients “apps.” But I’m not sure.

                                Stakeholder 2: Automations are often called “workflows,” I think. Or, maybe users think workflows are something different.

                                If a more user-friendly term emerges, ask the group if they can agree to use only that term moving forward. This way, the team can better align to the users’ language and mindset.

                                OK, moving on. 

                                If you have two or more objects that seem to overlap in purpose, ask one of these questions:

                                3. Are these the same thing? Or are these different? If they are not the same, how are they different?

                                You: Is a saved response the same as a template?

                                Stakeholder 1: Yes! Definitely.

                                Stakeholder 2: I don’t think so… A saved response is text with links and variables, but a template is more about the look and feel, like default fonts, colors, and placeholder images. 

                                Continue to build out your growing glossary of objects. And continue to capture areas of uncertainty in your “open questions” parking lot.

                                If you successfully determine that two similar things are, in fact, different, here’s your next follow-up question:

                                4. What’s the relationship between these objects?

                                You: Are saved responses and templates related in any way?

                                Stakeholder 3:  Yeah, a template can be applied to a saved response.

                                You, always with the follow-ups: When is the template applied to a saved response? Does that happen when the user is constructing the saved response? Or when they apply the saved response to an email? How does that actually work?

                                Listen. Capture uncertainty. Once the list of “open questions” grows to a critical mass, pause to start assigning questions to groups or individuals. Some questions might be for the dev team (hopefully at least one developer is in the room with you). One question might be specifically for someone who couldn’t make it to the workshop. And many questions will need to be labeled “user.” 

                                Do you see how we are building up to our UXR sales pitch?

                                5. Is this object in scope?

                                Your next question narrows the team’s focus toward what’s most important to your users. You can simply ask, “Are saved responses in scope for our first release?,” but I’ve got a better, more devious strategy.

                                By now, you should have a list of clearly defined objects. Ask participants to sort these objects from most to least important, either in small breakout groups or individually. Then, like you did with the definitions, have everyone reveal their sort order at once. Surprisingly—or not so surprisingly—it’s not unusual for the VP to rank something like “saved responses” as #2 while everyone else puts it at the bottom of the list. Try not to look too smug as you inevitably expose more misalignment.

                                I did this for a startup a few years ago. We posted the three groups’ wildly different sort orders on the whiteboard.

                                Here’s a snippet of the very messy middle from this session: three columns of object cards, showing the same cards prioritized completely differently by three different groups.

                                The CEO stood back, looked at it, and said, “This is why we haven’t been able to move forward in two years.”

                                Admittedly, it’s tragic to hear that, but as a professional, it feels pretty awesome to be the one who facilitated a watershed realization.

                                Once you have a good idea of in-scope, clearly defined things, this is when you move on to doing more relationship mapping.

                                6. Create a visual representation of the objects’ relationships

                                We’ve already done a bit of this while trying to determine if two things are different, but this time, ask the team about every potential relationship. For each object, ask how it relates to all the other objects. In what ways are the objects connected? To visualize all the connections, pull out your trusty boxes-and-arrows technique. Here, we are connecting our objects with verbs. I like to keep my verbs to simple “has a” and “has many” statements.

                                A work-in-progress system model of our new email solution.

                                This system modeling activity brings up all sorts of new questions:

                                • Can a saved response have attachments?
                                • Can a saved response use a template? If so, if an email uses a saved response with a template, can the user override that template?
                                • Do users want to see all the emails they sent that included a particular attachment? For example, “show me all the emails I sent with ProfessionalImage.jpg attached. I’ve changed my professional photo and I want to alert everyone to update it.” 

                                Solid answers might emerge directly from the workshop participants. Great! Capture that new shared understanding. But when uncertainty surfaces, continue to add questions to your growing parking lot.

                                Light the fuse

                                You’ve positioned the explosives all along the floodgates. Now you simply have to light the fuse and BOOM. Watch the buy-in for user research flooooow.

                                Before your workshop wraps up, have the group reflect on the list of open questions. Make plans for getting answers internally, then focus on the questions that need to be brought before users.

                                Here’s your final step. Take those questions you’ve compiled for user research and discuss the level of risk associated with NOT answering them. Ask, “if we design without an answer to this question, if we make up our own answer and we are wrong, how bad might that turn out?” 

                                With this methodology, we are cornering our decision-makers into advocating for user research as they themselves label questions as high-risk. Sorry, not sorry. 

                                Now is your moment of truth. With everyone in the room, ask for a reasonable budget of time and money to conduct 6–8 user interviews focused specifically on these questions. 

                                HOT TIP: if you are new to UX research, please note that you’ll likely need to rephrase the questions that came up during the workshop before you present them to users. Make sure your questions are open-ended and don’t lead the user into any default answers.

                                Final words: Hold the screen design!

                                Seriously, if at all possible, do not ever design screens again without first answering these fundamental questions: what are the objects and how do they relate?

                                I promise you this: if you can secure a shared understanding between the business, design, and development teams before you start designing screens, you will have less heartache and save more time and money, and (it almost feels like a bonus at this point!) users will be more receptive to what you put out into the world. 

                                I sincerely hope this helps you win time and budget to go talk to your users and gain clarity on what you are designing before you start building screens. If you find success using noun foraging and the Object Definition Workshop, there’s more where that came from in the rest of the ORCA process, which will help prevent even more late-in-the-game scope tugs-of-war and strategy pivots. 

                                All the best of luck! Now go sell research!

                                A Content Model Is Not a Design System

                                  Do you remember when having a great website was enough? Now, people are getting answers from Siri, Google search snippets, and mobile apps, not just our websites. Forward-thinking organizations have adopted an omnichannel content strategy, whose mission is to reach audiences across multiple digital channels and platforms.

                                  But how do you set up a content management system (CMS) to reach your audience now and in the future? I learned the hard way that creating a content model—a definition of content types, attributes, and relationships that let people and systems understand content—with my more familiar design-system thinking would capsize my customer’s omnichannel content strategy. You can avoid that outcome by creating content models that are semantic and that also connect related content. 

                                  I recently had the opportunity to lead the CMS implementation for a Fortune 500 company. The client was excited by the benefits of an omnichannel content strategy, including content reuse, multichannel marketing, and robot delivery—designing content to be intelligible to bots, Google knowledge panels, snippets, and voice user interfaces. 

                                  A content model is a critical foundation for an omnichannel content strategy, and for our content to be understood by multiple systems, the model needed semantic types—types named according to their meaning instead of their presentation. Our goal was to let authors create content and reuse it wherever it was relevant. But as the project proceeded, I realized that supporting content reuse at the scale that my customer needed required the whole team to recognize a new pattern.

                                  Despite our best intentions, we kept drawing from what we were more familiar with: design systems. Unlike web-focused content strategies, an omnichannel content strategy can’t rely on WYSIWYG tools for design and layout. Our tendency to approach the content model with our familiar design-system thinking constantly led us to veer away from one of the primary purposes of a content model: delivering content to audiences on multiple marketing channels.

                                  Two essential principles for an effective content model

                                  We needed to help our designers, developers, and stakeholders understand that we were doing something very different from their prior web projects, where it was natural for everyone to think about content as visual building blocks fitting into layouts. The previous approach was not only more familiar but also more intuitive—at least at first—because it made the designs feel more tangible. We discovered two principles that helped the team understand how a content model differs from the design systems that we were used to:

                                  1. Content models must define semantics instead of layout.
                                  2. And content models should connect content that belongs together.
                                  Semantic content models

                                  A semantic content model uses type and attribute names that reflect the meaning of the content, not how it will be displayed. For example, in a nonsemantic model, teams might create types like teasers, media blocks, and cards. Although these types might make it easy to lay out content, they don’t help delivery channels understand the content’s meaning, which in turn would have opened the door to the content being presented in each marketing channel. In contrast, a semantic content model uses type names like product, service, and testimonial so that each delivery channel can understand the content and use it as it sees fit. 

                                  When you’re creating a semantic content model, a great place to start is to look over the types and properties defined by Schema.org, a community-driven resource for type definitions that are intelligible to platforms like Google search.

                                  A semantic content model has several benefits:

                                  • Even if your team doesn’t care about omnichannel content, a semantic content model decouples content from its presentation so that teams can evolve the website’s design without needing to refactor its content. In this way, content can withstand disruptive website redesigns. 
                                  • A semantic content model also provides a competitive edge. By adding structured data based on Schema.org’s types and properties, a website can provide hints to help Google understand the content, display it in search snippets or knowledge panels, and use it to answer voice-interface user questions. Potential visitors could discover your content without ever setting foot in your website.
                                  • Beyond those practical benefits, you’ll also need a semantic content model if you want to deliver omnichannel content. To use the same content in multiple marketing channels, delivery channels need to be able to understand it. For example, if your content model were to provide a list of questions and answers, it could easily be rendered on a frequently asked questions (FAQ) page, but it could also be used in a voice interface or by a bot that answers common questions.

                                  For example, using a semantic content model for articles, events, people, and locations lets A List Apart provide cleanly structured data for search engines so that users can read the content on the website, in Google knowledge panels, and even with hypothetical voice interfaces in the future.

                                  Content models that connect

                                  After struggling to describe what makes a good content model, I’ve come to realize that the best models are those that are semantic and that also connect related content components (such as a FAQ item’s question and answer pair), instead of slicing up related content across disparate content components. A good content model connects content that should remain together so that multiple delivery channels can use it without needing to first put those pieces back together.

                                  Think about writing an article or essay. An article’s meaning and usefulness depends upon its parts being kept together. Would one of the headings or paragraphs be meaningful on their own without the context of the full article? On our project, our familiar design-system thinking often led us to want to create content models that would slice content into disparate chunks to fit the web-centric layout. This had a similar impact to an article that were to have been separated from its headline. Because we were slicing content into standalone pieces based on layout, content that belonged together became difficult to manage and nearly impossible for multiple delivery channels to understand.

                                  To illustrate, let’s look at how connecting related content applies in a real-world scenario. The design team for our customer presented a complex layout for a software product page that included multiple tabs and sections. Our instincts were to follow suit with the content model. Shouldn’t we make it as easy and as flexible as possible to add any number of tabs in the future?

                                  Because our design-system instincts were so familiar, it felt like we had needed a content type called “tab section” so that multiple tab sections could be added to a page. Each tab section would display various types of content. One tab might provide the software’s overview or its specifications. Another tab might provide a list of resources. 

                                  Our inclination to break down the content model into “tab section” pieces would have led to an unnecessarily complex model and a cumbersome editing experience, and it would have also created content that couldn’t have been understood by additional delivery channels. For example, how would another system have been able to tell which “tab section” referred to a product’s specifications or its resource list—would that other system have to have resorted to counting tab sections and content blocks? This would have prevented the tabs from ever being reordered, and it would have required adding logic in every other delivery channel to interpret the design system’s layout. Furthermore, if the customer were to have no longer wanted to display this content in a tab layout, it would have been tedious to migrate to a new content model to reflect the new page redesign.

                                  A content model based on design components is unnecessarily complex, and it’s unintelligible to systems.

                                  We had a breakthrough when we discovered that our customer had a specific purpose in mind for each tab: it would reveal specific information such as the software product’s overview, specifications, related resources, and pricing. Once implementation began, our inclination to focus on what’s visual and familiar had obscured the intent of the designs. With a little digging, it didn’t take long to realize that the concept of tabs wasn’t relevant to the content model. The meaning of the content that they were planning to display in the tabs was what mattered.

                                  In fact, the customer could have decided to display this content in a different way—without tabs—somewhere else. This realization prompted us to define content types for the software product based on the meaningful attributes that the customer had wanted to render on the web. There were obvious semantic attributes like name and description as well as rich attributes like screenshots, software requirements, and feature lists. The software’s product information stayed together because it wasn’t sliced across separate components like “tab sections” that were derived from the content’s presentation. Any delivery channel—including future ones—could understand and present this content.

                                  A good content model connects content that belongs together so it can be easily managed and reused. Conclusion

                                  In this omnichannel marketing project, we discovered that the best way to keep our content model on track was to ensure that it was semantic (with type and attribute names that reflected the meaning of the content) and that it kept content together that belonged together (instead of fragmenting it). These two concepts curtailed our temptation to shape the content model based on the design. So if you’re working on a content model to support an omnichannel content strategy—or even if you just want to make sure that Google and other interfaces understand your content—remember:

                                  • A design system isn’t a content model. Team members may be tempted to conflate them and to make your content model mirror your design system, so you should protect the semantic value and contextual structure of the content strategy during the entire implementation process. This will let every delivery channel consume the content without needing a magic decoder ring.
                                  • If your team is struggling to make this transition, you can still reap some of the benefits by using Schema.org–based structured data in your website. Even if additional delivery channels aren’t on the immediate horizon, the benefit to search engine optimization is a compelling reason on its own.
                                  • Additionally, remind the team that decoupling the content model from the design will let them update the designs more easily because they won’t be held back by the cost of content migrations. They’ll be able to create new designs without the obstacle of compatibility between the design and the content, and ​they’ll be ready for the next big thing. 

                                  By rigorously advocating for these principles, you’ll help your team treat content the way that it deserves—as the most critical asset in your user experience and the best way to connect with your audience.

                                  Design for Safety, An Excerpt

                                    Antiracist economist Kim Crayton says that “intention without strategy is chaos.” We’ve discussed how our biases, assumptions, and inattention toward marginalized and vulnerable groups lead to dangerous and unethical tech—but what, specifically, do we need to do to fix it? The intention to make our tech safer is not enough; we need a strategy.

                                    This chapter will equip you with that plan of action. It covers how to integrate safety principles into your design work in order to create tech that’s safe, how to convince your stakeholders that this work is necessary, and how to respond to the critique that what we actually need is more diversity. (Spoiler: we do, but diversity alone is not the antidote to fixing unethical, unsafe tech.)

                                    The process for inclusive safety

                                    When you are designing for safety, your goals are to:

                                    • identify ways your product can be used for abuse,
                                    • design ways to prevent the abuse, and
                                    • provide support for vulnerable users to reclaim power and control.

                                    The Process for Inclusive Safety is a tool to help you reach those goals (Fig 5.1). It’s a methodology I created in 2018 to capture the various techniques I was using when designing products with safety in mind. Whether you are creating an entirely new product or adding to an existing feature, the Process can help you make your product safe and inclusive. The Process includes five general areas of action:

                                    • Conducting research
                                    • Creating archetypes
                                    • Brainstorming problems
                                    • Designing solutions
                                    • Testing for safety
                                    Fig 5.1: Each aspect of the Process for Inclusive Safety can be incorporated into your design process where it makes the most sense for you. The times given are estimates to help you incorporate the stages into your design plan.

                                    The Process is meant to be flexible—it won’t make sense for teams to implement every step in some situations. Use the parts that are relevant to your unique work and context; this is meant to be something you can insert into your existing design practice.

                                    And once you use it, if you have an idea for making it better or simply want to provide context of how it helped your team, please get in touch with me. It’s a living document that I hope will continue to be a useful and realistic tool that technologists can use in their day-to-day work.

                                    If you’re working on a product specifically for a vulnerable group or survivors of some form of trauma, such as an app for survivors of domestic violence, sexual assault, or drug addiction, be sure to read Chapter 7, which covers that situation explicitly and should be handled a bit differently. The guidelines here are for prioritizing safety when designing a more general product that will have a wide user base (which, we already know from statistics, will include certain groups that should be protected from harm). Chapter 7 is focused on products that are specifically for vulnerable groups and people who have experienced trauma.

                                    Step 1: Conduct research

                                    Design research should include a broad analysis of how your tech might be weaponized for abuse as well as specific insights into the experiences of survivors and perpetrators of that type of abuse. At this stage, you and your team will investigate issues of interpersonal harm and abuse, and explore any other safety, security, or inclusivity issues that might be a concern for your product or service, like data security, racist algorithms, and harassment.

                                    Broad research

                                    Your project should begin with broad, general research into similar products and issues around safety and ethical concerns that have already been reported. For example, a team building a smart home device would do well to understand the multitude of ways that existing smart home devices have been used as tools of abuse. If your product will involve AI, seek to understand the potentials for racism and other issues that have been reported in existing AI products. Nearly all types of technology have some kind of potential or actual harm that’s been reported on in the news or written about by academics. Google Scholar is a useful tool for finding these studies.

                                    Specific research: Survivors

                                    When possible and appropriate, include direct research (surveys and interviews) with people who are experts in the forms of harm you have uncovered. Ideally, you’ll want to interview advocates working in the space of your research first so that you have a more solid understanding of the topic and are better equipped to not retraumatize survivors. If you’ve uncovered possible domestic violence issues, for example, the experts you’ll want to speak with are survivors themselves, as well as workers at domestic violence hotlines, shelters, other related nonprofits, and lawyers.

                                    Especially when interviewing survivors of any kind of trauma, it is important to pay people for their knowledge and lived experiences. Don’t ask survivors to share their trauma for free, as this is exploitative. While some survivors may not want to be paid, you should always make the offer in the initial ask. An alternative to payment is to donate to an organization working against the type of violence that the interviewee experienced. We’ll talk more about how to appropriately interview survivors in Chapter 6.

                                    Specific research: Abusers

                                    It’s unlikely that teams aiming to design for safety will be able to interview self-proclaimed abusers or people who have broken laws around things like hacking. Don’t make this a goal; rather, try to get at this angle in your general research. Aim to understand how abusers or bad actors weaponize technology to use against others, how they cover their tracks, and how they explain or rationalize the abuse.

                                    Step 2: Create archetypes

                                    Once you’ve finished conducting your research, use your insights to create abuser and survivor archetypes. Archetypes are not personas, as they’re not based on real people that you interviewed and surveyed. Instead, they’re based on your research into likely safety issues, much like when we design for accessibility: we don’t need to have found a group of blind or low-vision users in our interview pool to create a design that’s inclusive of them. Instead, we base those designs on existing research into what this group needs. Personas typically represent real users and include many details, while archetypes are broader and can be more generalized.

                                    The abuser archetype is someone who will look at the product as a tool to perform harm (Fig 5.2). They may be trying to harm someone they don’t know through surveillance or anonymous harassment, or they may be trying to control, monitor, abuse, or torment someone they know personally.

                                    Fig 5.2: Harry Oleson, an abuser archetype for a fitness product, is looking for ways to stalk his ex-girlfriend through the fitness apps she uses.

                                    The survivor archetype is someone who is being abused with the product. There are various situations to consider in terms of the archetype’s understanding of the abuse and how to put an end to it: Do they need proof of abuse they already suspect is happening, or are they unaware they’ve been targeted in the first place and need to be alerted (Fig 5.3)?

                                    Fig 5.3: The survivor archetype Lisa Zwaan suspects her husband is weaponizing their home’s IoT devices against her, but in the face of his insistence that she simply doesn’t understand how to use the products, she’s unsure. She needs some kind of proof of the abuse.

                                    You may want to make multiple survivor archetypes to capture a range of different experiences. They may know that the abuse is happening but not be able to stop it, like when an abuser locks them out of IoT devices; or they know it’s happening but don’t know how, such as when a stalker keeps figuring out their location (Fig 5.4). Include as many of these scenarios as you need to in your survivor archetype. You’ll use these later on when you design solutions to help your survivor archetypes achieve their goals of preventing and ending abuse.

                                    Fig 5.4: The survivor archetype Eric Mitchell knows he’s being stalked by his ex-boyfriend Rob but can’t figure out how Rob is learning his location information.

                                    It may be useful for you to create persona-like artifacts for your archetypes, such as the three examples shown. Instead of focusing on the demographic information we often see in personas, focus on their goals. The goals of the abuser will be to carry out the specific abuse you’ve identified, while the goals of the survivor will be to prevent abuse, understand that abuse is happening, make ongoing abuse stop, or regain control over the technology that’s being used for abuse. Later, you’ll brainstorm how to prevent the abuser’s goals and assist the survivor’s goals.

                                    And while the “abuser/survivor” model fits most cases, it doesn’t fit all, so modify it as you need to. For example, if you uncovered an issue with security, such as the ability for someone to hack into a home camera system and talk to children, the malicious hacker would get the abuser archetype and the child’s parents would get survivor archetype.

                                    Step 3: Brainstorm problems

                                    After creating archetypes, brainstorm novel abuse cases and safety issues. “Novel” means things not found in your research; you’re trying to identify completely new safety issues that are unique to your product or service. The goal with this step is to exhaust every effort of identifying harms your product could cause. You aren’t worrying about how to prevent the harm yet—that comes in the next step.

                                    How could your product be used for any kind of abuse, outside of what you’ve already identified in your research? I recommend setting aside at least a few hours with your team for this process.

                                    If you’re looking for somewhere to start, try doing a Black Mirror brainstorm. This exercise is based on the show Black Mirror, which features stories about the dark possibilities of technology. Try to figure out how your product would be used in an episode of the show—the most wild, awful, out-of-control ways it could be used for harm. When I’ve led Black Mirror brainstorms, participants usually end up having a good deal of fun (which I think is great—it’s okay to have fun when designing for safety!). I recommend time-boxing a Black Mirror brainstorm to half an hour, and then dialing it back and using the rest of the time thinking of more realistic forms of harm.

                                    After you’ve identified as many opportunities for abuse as possible, you may still not feel confident that you’ve uncovered every potential form of harm. A healthy amount of anxiety is normal when you’re doing this kind of work. It’s common for teams designing for safety to worry, “Have we really identified every possible harm? What if we’ve missed something?” If you’ve spent at least four hours coming up with ways your product could be used for harm and have run out of ideas, go to the next step.

                                    It’s impossible to guarantee you’ve thought of everything; instead of aiming for 100 percent assurance, recognize that you’ve taken this time and have done the best you can, and commit to continuing to prioritize safety in the future. Once your product is released, your users may identify new issues that you missed; aim to receive that feedback graciously and course-correct quickly.

                                    Step 4: Design solutions

                                    At this point, you should have a list of ways your product can be used for harm as well as survivor and abuser archetypes describing opposing user goals. The next step is to identify ways to design against the identified abuser’s goals and to support the survivor’s goals. This step is a good one to insert alongside existing parts of your design process where you’re proposing solutions for the various problems your research uncovered.

                                    Some questions to ask yourself to help prevent harm and support your archetypes include:

                                    • Can you design your product in such a way that the identified harm cannot happen in the first place? If not, what roadblocks can you put up to prevent the harm from happening?
                                    • How can you make the victim aware that abuse is happening through your product?
                                    • How can you help the victim understand what they need to do to make the problem stop?
                                    • Can you identify any types of user activity that would indicate some form of harm or abuse? Could your product help the user access support?

                                    In some products, it’s possible to proactively recognize that harm is happening. For example, a pregnancy app might be modified to allow the user to report that they were the victim of an assault, which could trigger an offer to receive resources for local and national organizations. This sort of proactiveness is not always possible, but it’s worth taking a half hour to discuss if any type of user activity would indicate some form of harm or abuse, and how your product could assist the user in receiving help in a safe manner.

                                    That said, use caution: you don’t want to do anything that could put a user in harm’s way if their devices are being monitored. If you do offer some kind of proactive help, always make it voluntary, and think through other safety issues, such as the need to keep the user in-app in case an abuser is checking their search history. We’ll walk through a good example of this in the next chapter.

                                    Step 5: Test for safety

                                    The final step is to test your prototypes from the point of view of your archetypes: the person who wants to weaponize the product for harm and the victim of the harm who needs to regain control over the technology. Just like any other kind of product testing, at this point you’ll aim to rigorously test out your safety solutions so that you can identify gaps and correct them, validate that your designs will help keep your users safe, and feel more confident releasing your product into the world.

                                    Ideally, safety testing happens along with usability testing. If you’re at a company that doesn’t do usability testing, you might be able to use safety testing to cleverly perform both; a user who goes through your design attempting to weaponize the product against someone else can also be encouraged to point out interactions or other elements of the design that don’t make sense to them.

                                    You’ll want to conduct safety testing on either your final prototype or the actual product if it’s already been released. There’s nothing wrong with testing an existing product that wasn’t designed with safety goals in mind from the onset—“retrofitting” it for safety is a good thing to do.

                                    Remember that testing for safety involves testing from the perspective of both an abuser and a survivor, though it may not make sense for you to do both. Alternatively, if you made multiple survivor archetypes to capture multiple scenarios, you’ll want to test from the perspective of each one.

                                    As with other sorts of usability testing, you as the designer are most likely too close to the product and its design by this point to be a valuable tester; you know the product too well. Instead of doing it yourself, set up testing as you would with other usability testing: find someone who is not familiar with the product and its design, set the scene, give them a task, encourage them to think out loud, and observe how they attempt to complete it.

                                    Abuser testing

                                    The goal of this testing is to understand how easy it is for someone to weaponize your product for harm. Unlike with usability testing, you want to make it impossible, or at least difficult, for them to achieve their goal. Reference the goals in the abuser archetype you created earlier, and use your product in an attempt to achieve them.

                                    For example, for a fitness app with GPS-enabled location features, we can imagine that the abuser archetype would have the goal of figuring out where his ex-girlfriend now lives. With this goal in mind, you’d try everything possible to figure out the location of another user who has their privacy settings enabled. You might try to see her running routes, view any available information on her profile, view anything available about her location (which she has set to private), and investigate the profiles of any other users somehow connected with her account, such as her followers.

                                    If by the end of this you’ve managed to uncover some of her location data, despite her having set her profile to private, you know now that your product enables stalking. Your next step is to go back to step 4 and figure out how to prevent this from happening. You may need to repeat the process of designing solutions and testing them more than once.

                                    Survivor testing

                                    Survivor testing involves identifying how to give information and power to the survivor. It might not always make sense based on the product or context. Thwarting the attempt of an abuser archetype to stalk someone also satisfies the goal of the survivor archetype to not be stalked, so separate testing wouldn’t be needed from the survivor’s perspective.

                                    However, there are cases where it makes sense. For example, for a smart thermostat, a survivor archetype’s goals would be to understand who or what is making the temperature change when they aren’t doing it themselves. You could test this by looking for the thermostat’s history log and checking for usernames, actions, and times; if you couldn’t find that information, you would have more work to do in step 4.

                                    Another goal might be regaining control of the thermostat once the survivor realizes the abuser is remotely changing its settings. Your test would involve attempting to figure out how to do this: are there instructions that explain how to remove another user and change the password, and are they easy to find? This might again reveal that more work is needed to make it clear to the user how they can regain control of the device or account.

                                    Stress testing

                                    To make your product more inclusive and compassionate, consider adding stress testing. This concept comes from Design for Real Life by Eric Meyer and Sara Wachter-Boettcher. The authors pointed out that personas typically center people who are having a good day—but real users are often anxious, stressed out, having a bad day, or even experiencing tragedy. These are called “stress cases,” and testing your products for users in stress-case situations can help you identify places where your design lacks compassion. Design for Real Life has more details about what it looks like to incorporate stress cases into your design as well as many other great tactics for compassionate design.

                                    Sustainable Web Design, An Excerpt

                                      In the 1950s, many in the elite running community had begun to believe it wasn’t possible to run a mile in less than four minutes. Runners had been attempting it since the late 19th century and were beginning to draw the conclusion that the human body simply wasn’t built for the task. 

                                      But on May 6, 1956, Roger Bannister took everyone by surprise. It was a cold, wet day in Oxford, England—conditions no one expected to lend themselves to record-setting—and yet Bannister did just that, running a mile in 3:59.4 and becoming the first person in the record books to run a mile in under four minutes. 

                                      This shift in the benchmark had profound effects; the world now knew that the four-minute mile was possible. Bannister’s record lasted only forty-six days, when it was snatched away by Australian runner John Landy. Then a year later, three runners all beat the four-minute barrier together in the same race. Since then, over 1,400 runners have officially run a mile in under four minutes; the current record is 3:43.13, held by Moroccan athlete Hicham El Guerrouj.

                                      We achieve far more when we believe that something is possible, and we will believe it’s possible only when we see someone else has already done it—and as with human running speed, so it is with what we believe are the hard limits for how a website needs to perform.

                                      Establishing standards for a sustainable web

                                      In most major industries, the key metrics of environmental performance are fairly well established, such as miles per gallon for cars or energy per square meter for homes. The tools and methods for calculating those metrics are standardized as well, which keeps everyone on the same page when doing environmental assessments. In the world of websites and apps, however, we aren’t held to any particular environmental standards, and only recently have gained the tools and methods we need to even make an environmental assessment.

                                      The primary goal in sustainable web design is to reduce carbon emissions. However, it’s almost impossible to actually measure the amount of CO2 produced by a web product. We can’t measure the fumes coming out of the exhaust pipes on our laptops. The emissions of our websites are far away, out of sight and out of mind, coming out of power stations burning coal and gas. We have no way to trace the electrons from a website or app back to the power station where the electricity is being generated and actually know the exact amount of greenhouse gas produced. So what do we do? 

                                      If we can’t measure the actual carbon emissions, then we need to find what we can measure. The primary factors that could be used as indicators of carbon emissions are:

                                      1. Data transfer 
                                      2. Carbon intensity of electricity

                                      Let’s take a look at how we can use these metrics to quantify the energy consumption, and in turn the carbon footprint, of the websites and web apps we create.

                                      Data transfer

                                      Most researchers use kilowatt-hours per gigabyte (kWh/GB) as a metric of energy efficiency when measuring the amount of data transferred over the internet when a website or application is used. This provides a great reference point for energy consumption and carbon emissions. As a rule of thumb, the more data transferred, the more energy used in the data center, telecoms networks, and end user devices.

                                      For web pages, data transfer for a single visit can be most easily estimated by measuring the page weight, meaning the transfer size of the page in kilobytes the first time someone visits the page. It’s fairly easy to measure using the developer tools in any modern web browser. Often your web hosting account will include statistics for the total data transfer of any web application (Fig 2.1).

                                      Fig 2.1: The Kinsta hosting dashboard displays data transfer alongside traffic volumes. If you divide data transfer by visits, you get the average data per visit, which can be used as a metric of efficiency.

                                      The nice thing about page weight as a metric is that it allows us to compare the efficiency of web pages on a level playing field without confusing the issue with constantly changing traffic volumes. 

                                      Reducing page weight requires a large scope. By early 2020, the median page weight was 1.97 MB for setups the HTTP Archive classifies as “desktop” and 1.77 MB for “mobile,” with desktop increasing 36 percent since January 2016 and mobile page weights nearly doubling in the same period (Fig 2.2). Roughly half of this data transfer is image files, making images the single biggest source of carbon emissions on the average website. 

                                      History clearly shows us that our web pages can be smaller, if only we set our minds to it. While most technologies become ever more energy efficient, including the underlying technology of the web such as data centers and transmission networks, websites themselves are a technology that becomes less efficient as time goes on.

                                      Fig 2.2: The historical page weight data from HTTP Archive can teach us a lot about what is possible in the future.

                                      You might be familiar with the concept of performance budgeting as a way of focusing a project team on creating faster user experiences. For example, we might specify that the website must load in a maximum of one second on a broadband connection and three seconds on a 3G connection. Much like speed limits while driving, performance budgets are upper limits rather than vague suggestions, so the goal should always be to come in under budget.

                                      Designing for fast performance does often lead to reduced data transfer and emissions, but it isn’t always the case. Web performance is often more about the subjective perception of load times than it is about the true efficiency of the underlying system, whereas page weight and transfer size are more objective measures and more reliable benchmarks for sustainable web design. 

                                      We can set a page weight budget in reference to a benchmark of industry averages, using data from sources like HTTP Archive. We can also benchmark page weight against competitors or the old version of the website we’re replacing. For example, we might set a maximum page weight budget as equal to our most efficient competitor, or we could set the benchmark lower to guarantee we are best in class. 

                                      If we want to take it to the next level, then we could also start looking at the transfer size of our web pages for repeat visitors. Although page weight for the first time someone visits is the easiest thing to measure, and easy to compare on a like-for-like basis, we can learn even more if we start looking at transfer size in other scenarios too. For example, visitors who load the same page multiple times will likely have a high percentage of the files cached in their browser, meaning they don’t need to transfer all of the files on subsequent visits. Likewise, a visitor who navigates to new pages on the same website will likely not need to load the full page each time, as some global assets from areas like the header and footer may already be cached in their browser. Measuring transfer size at this next level of detail can help us learn even more about how we can optimize efficiency for users who regularly visit our pages, and enable us to set page weight budgets for additional scenarios beyond the first visit.

                                      Page weight budgets are easy to track throughout a design and development process. Although they don’t actually tell us carbon emission and energy consumption analytics directly, they give us a clear indication of efficiency relative to other websites. And as transfer size is an effective analog for energy consumption, we can actually use it to estimate energy consumption too.

                                      In summary, reduced data transfer translates to energy efficiency, a key factor to reducing carbon emissions of web products. The more efficient our products, the less electricity they use, and the less fossil fuels need to be burned to produce the electricity to power them. But as we’ll see next, since all web products demand some power, it’s important to consider the source of that electricity, too.

                                      Carbon intensity of electricity

                                      Regardless of energy efficiency, the level of pollution caused by digital products depends on the carbon intensity of the energy being used to power them. Carbon intensity is a term used to define the grams of CO2 produced for every kilowatt-hour of electricity (gCO2/kWh). This varies widely, with renewable energy sources and nuclear having an extremely low carbon intensity of less than 10 gCO2/kWh (even when factoring in their construction); whereas fossil fuels have very high carbon intensity of approximately 200–400 gCO2/kWh. 

                                      Most electricity comes from national or state grids, where energy from a variety of different sources is mixed together with varying levels of carbon intensity. The distributed nature of the internet means that a single user of a website or app might be using energy from multiple different grids simultaneously; a website user in Paris uses electricity from the French national grid to power their home internet and devices, but the website’s data center could be in Dallas, USA, pulling electricity from the Texas grid, while the telecoms networks use energy from everywhere between Dallas and Paris.

                                      We don’t have control over the full energy supply of web services, but we do have some control over where we host our projects. With a data center using a significant proportion of the energy of any website, locating the data center in an area with low carbon energy will tangibly reduce its carbon emissions. Danish startup Tomorrow reports and maps this user-contributed data, and a glance at their map shows how, for example, choosing a data center in France will have significantly lower carbon emissions than a data center in the Netherlands (Fig 2.3).

                                      Fig 2.3: Tomorrow’s electricityMap shows live data for the carbon intensity of electricity by country.

                                      That said, we don’t want to locate our servers too far away from our users; it takes energy to transmit data through the telecom’s networks, and the further the data travels, the more energy is consumed. Just like food miles, we can think of the distance from the data center to the website’s core user base as “megabyte miles”—and we want it to be as small as possible.

                                      Using the distance itself as a benchmark, we can use website analytics to identify the country, state, or even city where our core user group is located and measure the distance from that location to the data center used by our hosting company. This will be a somewhat fuzzy metric as we don’t know the precise center of mass of our users or the exact location of a data center, but we can at least get a rough idea. 

                                      For example, if a website is hosted in London but the primary user base is on the West Coast of the USA, then we could look up the distance from London to San Francisco, which is 5,300 miles. That’s a long way! We can see that hosting it somewhere in North America, ideally on the West Coast, would significantly reduce the distance and thus the energy used to transmit the data. In addition, locating our servers closer to our visitors helps reduce latency and delivers better user experience, so it’s a win-win.

                                      Converting it back to carbon emissions

                                      If we combine carbon intensity with a calculation for energy consumption, we can calculate the carbon emissions of our websites and apps. A tool my team created does this by measuring the data transfer over the wire when loading a web page, calculating the amount of electricity associated, and then converting that into a figure for CO2 (Fig 2.4). It also factors in whether or not the web hosting is powered by renewable energy.

                                      If you want to take it to the next level and tailor the data more accurately to the unique aspects of your project, the Energy and Emissions Worksheet accompanying this book shows you how.

                                      Fig 2.4: The Website Carbon Calculator shows how the Riverford Organic website embodies their commitment to sustainability, being both low carbon and hosted in a data center using renewable energy.

                                      With the ability to calculate carbon emissions for our projects, we could actually take a page weight budget one step further and set carbon budgets as well. CO2 is not a metric commonly used in web projects; we’re more familiar with kilobytes and megabytes, and can fairly easily look at design options and files to assess how big they are. Translating that into carbon adds a layer of abstraction that isn’t as intuitive—but carbon budgets do focus our minds on the primary thing we’re trying to reduce, and support the core objective of sustainable web design: reducing carbon emissions.

                                      Browser Energy

                                      Data transfer might be the simplest and most complete analog for energy consumption in our digital projects, but by giving us one number to represent the energy used in the data center, the telecoms networks, and the end user’s devices, it can’t offer us insights into the efficiency in any specific part of the system.

                                      One part of the system we can look at in more detail is the energy used by end users’ devices. As front-end web technologies become more advanced, the computational load is increasingly moving from the data center to users’ devices, whether they be phones, tablets, laptops, desktops, or even smart TVs. Modern web browsers allow us to implement more complex styling and animation on the fly using CSS and JavaScript. Furthermore, JavaScript libraries such as Angular and React allow us to create applications where the “thinking” work is done partly or entirely in the browser. 

                                      All of these advances are exciting and open up new possibilities for what the web can do to serve society and create positive experiences. However, more computation in the user’s web browser means more energy used by their devices. This has implications not just environmentally, but also for user experience and inclusivity. Applications that put a heavy processing load on the user’s device can inadvertently exclude users with older, slower devices and cause batteries on phones and laptops to drain faster. Furthermore, if we build web applications that require the user to have up-to-date, powerful devices, people throw away old devices much more frequently. This isn’t just bad for the environment, but it puts a disproportionate financial burden on the poorest in society.

                                      In part because the tools are limited, and partly because there are so many different models of devices, it’s difficult to measure website energy consumption on end users’ devices. One tool we do currently have is the Energy Impact monitor inside the developer console of the Safari browser (Fig 2.5).

                                      Fig 2.5: The Energy Impact meter in Safari (on the right) shows how a website consumes CPU energy.

                                      You know when you load a website and your computer’s cooling fans start spinning so frantically you think it might actually take off? That’s essentially what this tool is measuring. 

                                      It shows us the percentage of CPU used and the duration of CPU usage when loading the web page, and uses these figures to generate an energy impact rating. It doesn’t give us precise data for the amount of electricity used in kilowatts, but the information it does provide can be used to benchmark how efficiently your websites use energy and set targets for improvement.

                                      Voice Content and Usability

                                        We’ve been having conversations for thousands of years. Whether to convey information, conduct transactions, or simply to check in on one another, people have yammered away, chattering and gesticulating, through spoken conversation for countless generations. Only in the last few millennia have we begun to commit our conversations to writing, and only in the last few decades have we begun to outsource them to the computer, a machine that shows much more affinity for written correspondence than for the slangy vagaries of spoken language.

                                        Computers have trouble because between spoken and written language, speech is more primordial. To have successful conversations with us, machines must grapple with the messiness of human speech: the disfluencies and pauses, the gestures and body language, and the variations in word choice and spoken dialect that can stymie even the most carefully crafted human-computer interaction. In the human-to-human scenario, spoken language also has the privilege of face-to-face contact, where we can readily interpret nonverbal social cues.

                                        In contrast, written language immediately concretizes as we commit it to record and retains usages long after they become obsolete in spoken communication (the salutation “To whom it may concern,” for example), generating its own fossil record of outdated terms and phrases. Because it tends to be more consistent, polished, and formal, written text is fundamentally much easier for machines to parse and understand.

                                        Spoken language has no such luxury. Besides the nonverbal cues that decorate conversations with emphasis and emotional context, there are also verbal cues and vocal behaviors that modulate conversation in nuanced ways: how something is said, not what. Whether rapid-fire, low-pitched, or high-decibel, whether sarcastic, stilted, or sighing, our spoken language conveys much more than the written word could ever muster. So when it comes to voice interfaces—the machines we conduct spoken conversations with—we face exciting challenges as designers and content strategists.

                                        Voice Interactions

                                        We interact with voice interfaces for a variety of reasons, but according to Michael McTear, Zoraida Callejas, and David Griol in The Conversational Interface, those motivations by and large mirror the reasons we initiate conversations with other people, too (http://bkaprt.com/vcu36/01-01). Generally, we start up a conversation because:

                                        • we need something done (such as a transaction),
                                        • we want to know something (information of some sort), or
                                        • we are social beings and want someone to talk to (conversation for conversation’s sake).

                                        These three categories—which I call transactional, informational, and prosocial—also characterize essentially every voice interaction: a single conversation from beginning to end that realizes some outcome for the user, starting with the voice interface’s first greeting and ending with the user exiting the interface. Note here that a conversation in our human sense—a chat between people that leads to some result and lasts an arbitrary length of time—could encompass multiple transactional, informational, and prosocial voice interactions in succession. In other words, a voice interaction is a conversation, but a conversation is not necessarily a single voice interaction.

                                        Purely prosocial conversations are more gimmicky than captivating in most voice interfaces, because machines don’t yet have the capacity to really want to know how we’re doing and to do the sort of glad-handing humans crave. There’s also ongoing debate as to whether users actually prefer the sort of organic human conversation that begins with a prosocial voice interaction and shifts seamlessly into other types. In fact, in Voice User Interface Design, Michael Cohen, James Giangola, and Jennifer Balogh recommend sticking to users’ expectations by mimicking how they interact with other voice interfaces rather than trying too hard to be human—potentially alienating them in the process (http://bkaprt.com/vcu36/01-01).

                                        That leaves two genres of conversations we can have with one another that a voice interface can easily have with us, too: a transactional voice interaction realizing some outcome (“buy iced tea”) and an informational voice interaction teaching us something new (“discuss a musical”).

                                        Transactional voice interactions

                                        Unless you’re tapping buttons on a food delivery app, you’re generally having a conversation—and therefore a voice interaction—when you order a Hawaiian pizza with extra pineapple. Even when we walk up to the counter and place an order, the conversation quickly pivots from an initial smattering of neighborly small talk to the real mission at hand: ordering a pizza (generously topped with pineapple, as it should be).

                                        Alison: Hey, how’s it going?

                                        Burhan: Hi, welcome to Crust Deluxe! It’s cold out there. How can I help you?

                                        Alison: Can I get a Hawaiian pizza with extra pineapple?

                                        Burhan: Sure, what size?

                                        Alison: Large.

                                        Burhan: Anything else?

                                        Alison: No thanks, that’s it.

                                        Burhan: Something to drink?

                                        Alison: I’ll have a bottle of Coke.

                                        Burhan: You got it. That’ll be $13.55 and about fifteen minutes.

                                        Each progressive disclosure in this transactional conversation reveals more and more of the desired outcome of the transaction: a service rendered or a product delivered. Transactional conversations have certain key traits: they’re direct, to the point, and economical. They quickly dispense with pleasantries.

                                        Informational voice interactions

                                        Meanwhile, some conversations are primarily about obtaining information. Though Alison might visit Crust Deluxe with the sole purpose of placing an order, she might not actually want to walk out with a pizza at all. She might be just as interested in whether they serve halal or kosher dishes, gluten-free options, or something else. Here, though we again have a prosocial mini-conversation at the beginning to establish politeness, we’re after much more.

                                        Alison: Hey, how’s it going?

                                        Burhan: Hi, welcome to Crust Deluxe! It’s cold out there. How can I help you?

                                        Alison: Can I ask a few questions?

                                        Burhan: Of course! Go right ahead.

                                        Alison: Do you have any halal options on the menu?

                                        Burhan: Absolutely! We can make any pie halal by request. We also have lots of vegetarian, ovo-lacto, and vegan options. Are you thinking about any other dietary restrictions?

                                        Alison: What about gluten-free pizzas?

                                        Burhan: We can definitely do a gluten-free crust for you, no problem, for both our deep-dish and thin-crust pizzas. Anything else I can answer for you?

                                        Alison: That’s it for now. Good to know. Thanks!

                                        Burhan: Anytime, come back soon!

                                        This is a very different dialogue. Here, the goal is to get a certain set of facts. Informational conversations are investigative quests for the truth—research expeditions to gather data, news, or facts. Voice interactions that are informational might be more long-winded than transactional conversations by necessity. Responses tend to be lengthier, more informative, and carefully communicated so the customer understands the key takeaways.

                                        Voice Interfaces

                                        At their core, voice interfaces employ speech to support users in reaching their goals. But simply because an interface has a voice component doesn’t mean that every user interaction with it is mediated through voice. Because multimodal voice interfaces can lean on visual components like screens as crutches, we’re most concerned in this book with pure voice interfaces, which depend entirely on spoken conversation, lack any visual component whatsoever, and are therefore much more nuanced and challenging to tackle.

                                        Though voice interfaces have long been integral to the imagined future of humanity in science fiction, only recently have those lofty visions become fully realized in genuine voice interfaces.

                                        Interactive voice response (IVR) systems

                                        Though written conversational interfaces have been fixtures of computing for many decades, voice interfaces first emerged in the early 1990s with text-to-speech (TTS) dictation programs that recited written text aloud, as well as speech-enabled in-car systems that gave directions to a user-provided address. With the advent of interactive voice response (IVR) systems, intended as an alternative to overburdened customer service representatives, we became acquainted with the first true voice interfaces that engaged in authentic conversation.

                                        IVR systems allowed organizations to reduce their reliance on call centers but soon became notorious for their clunkiness. Commonplace in the corporate world, these systems were primarily designed as metaphorical switchboards to guide customers to a real phone agent (“Say Reservations to book a flight or check an itinerary”); chances are you will enter a conversation with one when you call an airline or hotel conglomerate. Despite their functional issues and users’ frustration with their inability to speak to an actual human right away, IVR systems proliferated in the early 1990s across a variety of industries (http://bkaprt.com/vcu36/01-02, PDF).

                                        While IVR systems are great for highly repetitive, monotonous conversations that generally don’t veer from a single format, they have a reputation for less scintillating conversation than we’re used to in real life (or even in science fiction).

                                        Screen readers

                                        Parallel to the evolution of IVR systems was the invention of the screen reader, a tool that transcribes visual content into synthesized speech. For Blind or visually impaired website users, it’s the predominant method of interacting with text, multimedia, or form elements. Screen readers represent perhaps the closest equivalent we have today to an out-of-the-box implementation of content delivered through voice.

                                        Among the first screen readers known by that moniker was the Screen Reader for the BBC Micro and NEEC Portable developed by the Research Centre for the Education of the Visually Handicapped (RCEVH) at the University of Birmingham in 1986 (http://bkaprt.com/vcu36/01-03). That same year, Jim Thatcher created the first IBM Screen Reader for text-based computers, later recreated for computers with graphical user interfaces (GUIs) (http://bkaprt.com/vcu36/01-04).

                                        With the rapid growth of the web in the 1990s, the demand for accessible tools for websites exploded. Thanks to the introduction of semantic HTML and especially ARIA roles beginning in 2008, screen readers started facilitating speedy interactions with web pages that ostensibly allow disabled users to traverse the page as an aural and temporal space rather than a visual and physical one. In other words, screen readers for the web “provide mechanisms that translate visual design constructs—proximity, proportion, etc.—into useful information,” writes Aaron Gustafson in A List Apart. “At least they do when documents are authored thoughtfully” (http://bkaprt.com/vcu36/01-05).

                                        Though deeply instructive for voice interface designers, there’s one significant problem with screen readers: they’re difficult to use and unremittingly verbose. The visual structures of websites and web navigation don’t translate well to screen readers, sometimes resulting in unwieldy pronouncements that name every manipulable HTML element and announce every formatting change. For many screen reader users, working with web-based interfaces exacts a cognitive toll.

                                        In Wired, accessibility advocate and voice engineer Chris Maury considers why the screen reader experience is ill-suited to users relying on voice:

                                        From the beginning, I hated the way that Screen Readers work. Why are they designed the way they are? It makes no sense to present information visually and then, and only then, translate that into audio. All of the time and energy that goes into creating the perfect user experience for an app is wasted, or even worse, adversely impacting the experience for blind users. (http://bkaprt.com/vcu36/01-06)

                                        In many cases, well-designed voice interfaces can speed users to their destination better than long-winded screen reader monologues. After all, visual interface users have the benefit of darting around the viewport freely to find information, ignoring areas irrelevant to them. Blind users, meanwhile, are obligated to listen to every utterance synthesized into speech and therefore prize brevity and efficiency. Disabled users who have long had no choice but to employ clunky screen readers may find that voice interfaces, particularly more modern voice assistants, offer a more streamlined experience.

                                        Voice assistants

                                        When we think of voice assistants (the subset of voice interfaces now commonplace in living rooms, smart homes, and offices), many of us immediately picture HAL from 2001: A Space Odyssey or hear Majel Barrett’s voice as the omniscient computer in Star Trek. Voice assistants are akin to personal concierges that can answer questions, schedule appointments, conduct searches, and perform other common day-to-day tasks. And they’re rapidly gaining more attention from accessibility advocates for their assistive potential.

                                        Before the earliest IVR systems found success in the enterprise, Apple published a demonstration video in 1987 depicting the Knowledge Navigator, a voice assistant that could transcribe spoken words and recognize human speech to a great degree of accuracy. Then, in 2001, Tim Berners-Lee and others formulated their vision for a Semantic Web “agent” that would perform typical errands like “checking calendars, making appointments, and finding locations” (http://bkaprt.com/vcu36/01-07, behind paywall). It wasn’t until 2011 that Apple’s Siri finally entered the picture, making voice assistants a tangible reality for consumers.

                                        Thanks to the plethora of voice assistants available today, there is considerable variation in how programmable and customizable certain voice assistants are over others (Fig 1.1). At one extreme, everything except vendor-provided features is locked down; for example, at the time of their release, the core functionality of Apple’s Siri and Microsoft’s Cortana couldn’t be extended beyond their existing capabilities. Even today, it isn’t possible to program Siri to perform arbitrary functions, because there’s no means by which developers can interact with Siri at a low level, apart from predefined categories of tasks like sending messages, hailing rideshares, making restaurant reservations, and certain others.

                                        At the opposite end of the spectrum, voice assistants like Amazon Alexa and Google Home offer a core foundation on which developers can build custom voice interfaces. For this reason, programmable voice assistants that lend themselves to customization and extensibility are becoming increasingly popular for developers who feel stifled by the limitations of Siri and Cortana. Amazon offers the Alexa Skills Kit, a developer framework for building custom voice interfaces for Amazon Alexa, while Google Home offers the ability to program arbitrary Google Assistant skills. Today, users can choose from among thousands of custom-built skills within both the Amazon Alexa and Google Assistant ecosystems.

                                        Fig 1.1: Voice assistants like Amazon Alexa and Google Home tend to be more programmable, and thus more flexible, than their counterpart Apple Siri.

                                        As corporations like Amazon, Apple, Microsoft, and Google continue to stake their territory, they’re also selling and open-sourcing an unprecedented array of tools and frameworks for designers and developers that aim to make building voice interfaces as easy as possible, even without code.

                                        Often by necessity, voice assistants like Amazon Alexa tend to be monochannel—they’re tightly coupled to a device and can’t be accessed on a computer or smartphone instead. By contrast, many development platforms like Google’s Dialogflow have introduced omnichannel capabilities so users can build a single conversational interface that then manifests as a voice interface, textual chatbot, and IVR system upon deployment. I don’t prescribe any specific implementation approaches in this design-focused book, but in Chapter 4 we’ll get into some of the implications these variables might have on the way you build out your design artifacts.

                                        Voice Content

                                        Simply put, voice content is content delivered through voice. To preserve what makes human conversation so compelling in the first place, voice content needs to be free-flowing and organic, contextless and concise—everything written content isn’t.

                                        Our world is replete with voice content in various forms: screen readers reciting website content, voice assistants rattling off a weather forecast, and automated phone hotline responses governed by IVR systems. In this book, we’re most concerned with content delivered auditorily—not as an option, but as a necessity.

                                        For many of us, our first foray into informational voice interfaces will be to deliver content to users. There’s only one problem: any content we already have isn’t in any way ready for this new habitat. So how do we make the content trapped on our websites more conversational? And how do we write new copy that lends itself to voice interactions?

                                        Lately, we’ve begun slicing and dicing our content in unprecedented ways. Websites are, in many respects, colossal vaults of what I call macrocontent: lengthy prose that can extend for infinitely scrollable miles in a browser window, like microfilm viewers of newspaper archives. Back in 2002, well before the present-day ubiquity of voice assistants, technologist Anil Dash defined microcontent as permalinked pieces of content that stay legible regardless of environment, such as email or text messages:

                                        A day’s weather forcast [sic], the arrival and departure times for an airplane flight, an abstract from a long publication, or a single instant message can all be examples of microcontent. (http://bkaprt.com/vcu36/01-08)

                                        I’d update Dash’s definition of microcontent to include all examples of bite-sized content that go well beyond written communiqués. After all, today we encounter microcontent in interfaces where a small snippet of copy is displayed alone, unmoored from the browser, like a textbot confirmation of a restaurant reservation. Microcontent offers the best opportunity to gauge how your content can be stretched to the very edges of its capabilities, informing delivery channels both established and novel.

                                        As microcontent, voice content is unique because it’s an example of how content is experienced in time rather than in space. We can glance at a digital sign underground for an instant and know when the next train is arriving, but voice interfaces hold our attention captive for periods of time that we can’t easily escape or skip, something screen reader users are all too familiar with.

                                        Because microcontent is fundamentally made up of isolated blobs with no relation to the channels where they’ll eventually end up, we need to ensure that our microcontent truly performs well as voice content—and that means focusing on the two most important traits of robust voice content: voice content legibility and voice content discoverability.

                                        Fundamentally, the legibility and discoverability of our voice content both have to do with how voice content manifests in perceived time and space.

                                        Designing for the Unexpected

                                          I’m not sure when I first heard this quote, but it’s something that has stayed with me over the years. How do you create services for situations you can’t imagine? Or design products that work on devices yet to be invented?

                                          Flash, Photoshop, and responsive design

                                          When I first started designing websites, my go-to software was Photoshop. I created a 960px canvas and set about creating a layout that I would later drop content in. The development phase was about attaining pixel-perfect accuracy using fixed widths, fixed heights, and absolute positioning.

                                          Ethan Marcotte’s talk at An Event Apart and subsequent article “Responsive Web Design” in A List Apart in 2010 changed all this. I was sold on responsive design as soon as I heard about it, but I was also terrified. The pixel-perfect designs full of magic numbers that I had previously prided myself on producing were no longer good enough.

                                          The fear wasn’t helped by my first experience with responsive design. My first project was to take an existing fixed-width website and make it responsive. What I learned the hard way was that you can’t just add responsiveness at the end of a project. To create fluid layouts, you need to plan throughout the design phase.

                                          A new way to design

                                          Designing responsive or fluid sites has always been about removing limitations, producing content that can be viewed on any device. It relies on the use of percentage-based layouts, which I initially achieved with native CSS and utility classes:

                                          .column-span-6 {
                                            width: 49%;
                                            float: left;
                                            margin-right: 0.5%;
                                            margin-left: 0.5%;
                                          }
                                          
                                          
                                          .column-span-4 {
                                            width: 32%;
                                            float: left;
                                            margin-right: 0.5%;
                                            margin-left: 0.5%;
                                          }
                                          
                                          .column-span-3 {
                                            width: 24%;
                                            float: left;
                                            margin-right: 0.5%;
                                            margin-left: 0.5%;
                                          }

                                          Then with Sass so I could take advantage of @includes to re-use repeated blocks of code and move back to more semantic markup:

                                          .logo {
                                            @include colSpan(6);
                                          }
                                          
                                          .search {
                                            @include colSpan(3);
                                          }
                                          
                                          .social-share {
                                            @include colSpan(3);
                                          }
                                          Media queries

                                          The second ingredient for responsive design is media queries. Without them, content would shrink to fit the available space regardless of whether that content remained readable (The exact opposite problem occurred with the introduction of a mobile-first approach).

                                          Components becoming too small at mobile breakpoints

                                          Media queries prevented this by allowing us to add breakpoints where the design could adapt. Like most people, I started out with three breakpoints: one for desktop, one for tablets, and one for mobile. Over the years, I added more and more for phablets, wide screens, and so on. 

                                          For years, I happily worked this way and improved both my design and front-end skills in the process. The only problem I encountered was making changes to content, since with our Sass grid system in place, there was no way for the site owners to add content without amending the markup—something a small business owner might struggle with. This is because each row in the grid was defined using a div as a container. Adding content meant creating new row markup, which requires a level of HTML knowledge.

                                          Row markup was a staple of early responsive design, present in all the widely used frameworks like Bootstrap and Skeleton.

                                          <section class="row">
                                            <div class="column-span-4">1 of 7</div>
                                            <div class="column-span-4">2 of 7</div>
                                            <div class="column-span-4">3 of 7</div>
                                          </section>
                                          
                                          <section class="row">
                                            <div class="column-span-4">4 of 7</div>
                                            <div class="column-span-4">5 of 7</div>
                                            <div class="column-span-4">6 of 7</div>
                                          </section>
                                          
                                          <section class="row">
                                            <div class="column-span-4">7 of 7</div>
                                          </section>
                                          Components placed in the rows of a Sass grid

                                          Another problem arose as I moved from a design agency building websites for small- to medium-sized businesses, to larger in-house teams where I worked across a suite of related sites. In those roles I started to work much more with reusable components. 

                                          Our reliance on media queries resulted in components that were tied to common viewport sizes. If the goal of component libraries is reuse, then this is a real problem because you can only use these components if the devices you’re designing for correspond to the viewport sizes used in the pattern library—in the process not really hitting that “devices that don’t yet exist”  goal.

                                          Then there’s the problem of space. Media queries allow components to adapt based on the viewport size, but what if I put a component into a sidebar, like in the figure below?

                                          Components responding to the viewport width with media queries Container queries: our savior or a false dawn?

                                          Container queries have long been touted as an improvement upon media queries, but at the time of writing are unsupported in most browsers. There are JavaScript workarounds, but they can create dependency and compatibility issues. The basic theory underlying container queries is that elements should change based on the size of their parent container and not the viewport width, as seen in the following illustrations.

                                          Components responding to their parent container with container queries

                                          One of the biggest arguments in favor of container queries is that they help us create components or design patterns that are truly reusable because they can be picked up and placed anywhere in a layout. This is an important step in moving toward a form of component-based design that works at any size on any device.

                                          In other words, responsive components to replace responsive layouts.

                                          Container queries will help us move from designing pages that respond to the browser or device size to designing components that can be placed in a sidebar or in the main content, and respond accordingly.

                                          My concern is that we are still using layout to determine when a design needs to adapt. This approach will always be restrictive, as we will still need pre-defined breakpoints. For this reason, my main question with container queries is, How would we decide when to change the CSS used by a component? 

                                          A component library removed from context and real content is probably not the best place for that decision. 

                                          As the diagrams below illustrate, we can use container queries to create designs for specific container widths, but what if I want to change the design based on the image size or ratio?

                                          Cards responding to their parent container with container queries Cards responding based on their own content

                                          In this example, the dimensions of the container are not what should dictate the design; rather, the image is.

                                          It’s hard to say for sure whether container queries will be a success story until we have solid cross-browser support for them. Responsive component libraries would definitely evolve how we design and would improve the possibilities for reuse and design at scale. But maybe we will always need to adjust these components to suit our content.

                                          CSS is changing

                                          Whilst the container query debate rumbles on, there have been numerous advances in CSS that change the way we think about design. The days of fixed-width elements measured in pixels and floated div elements used to cobble layouts together are long gone, consigned to history along with table layouts. Flexbox and CSS Grid have revolutionized layouts for the web. We can now create elements that wrap onto new rows when they run out of space, not when the device changes.

                                          .wrapper {
                                            display: grid;
                                            grid-template-columns: repeat(auto-fit, 450px);
                                            gap: 10px;
                                          }

                                          The repeat() function paired with auto-fit or auto-fill allows us to specify how much space each column should use while leaving it up to the browser to decide when to spill the columns onto a new line. Similar things can be achieved with Flexbox, as elements can wrap over multiple rows and “flex” to fill available space. 

                                          .wrapper {
                                            display: flex;
                                            flex-wrap: wrap;
                                            justify-content: space-between;
                                          }
                                          
                                          .child {
                                            flex-basis: 32%;
                                            margin-bottom: 20px;
                                          }

                                          The biggest benefit of all this is you don’t need to wrap elements in container rows. Without rows, content isn’t tied to page markup in quite the same way, allowing for removals or additions of content without additional development.

                                          A traditional Grid layout without the usual row containers

                                          This is a big step forward when it comes to creating designs that allow for evolving content, but the real game changer for flexible designs is CSS Subgrid. 

                                          Remember the days of crafting perfectly aligned interfaces, only for the customer to add an unbelievably long header almost as soon as they're given CMS access, like the illustration below?

                                          Cards unable to respond to a sibling’s content changes

                                          Subgrid allows elements to respond to adjustments in their own content and in the content of sibling elements, helping us create designs more resilient to change.

                                          Cards responding to content in sibling cards
                                          .wrapper {
                                            display: grid;
                                            grid-template-columns: repeat(auto-fit, minmax(150px, 1fr));
                                               grid-template-rows: auto 1fr auto;
                                            gap: 10px;
                                          }
                                          
                                          .sub-grid {
                                            display: grid;
                                            grid-row: span 3;
                                            grid-template-rows: subgrid; /* sets rows to parent grid */
                                          }

                                          CSS Grid allows us to separate layout and content, thereby enabling flexible designs. Meanwhile, Subgrid allows us to create designs that can adapt in order to suit morphing content. Subgrid at the time of writing is only supported in Firefox but the above code can be implemented behind an @supports feature query. 

                                          Intrinsic layouts 

                                          I’d be remiss not to mention intrinsic layouts, the term created by Jen Simmons to describe a mixture of new and old CSS features used to create layouts that respond to available space. 

                                          Responsive layouts have flexible columns using percentages. Intrinsic layouts, on the other hand, use the fr unit to create flexible columns that won’t ever shrink so much that they render the content illegible.

                                          fr units is a way to say I want you to distribute the extra space in this way, but...don’t ever make it smaller than the content that’s inside of it.

                                          —Jen Simmons, “Designing Intrinsic Layouts”

                                          Intrinsic layouts can also utilize a mixture of fixed and flexible units, allowing the content to dictate the space it takes up.

                                          Slide from “Designing Intrinsic Layouts” by Jen Simmons

                                          What makes intrinsic design stand out is that it not only creates designs that can withstand future devices but also helps scale design without losing flexibility. Components and patterns can be lifted and reused without the prerequisite of having the same breakpoints or the same amount of content as in the previous implementation. 

                                          We can now create designs that adapt to the space they have, the content within them, and the content around them. With an intrinsic approach, we can construct responsive components without depending on container queries.

                                          Another 2010 moment?

                                          This intrinsic approach should in my view be every bit as groundbreaking as responsive web design was ten years ago. For me, it’s another “everything changed” moment. 

                                          But it doesn’t seem to be moving quite as fast; I haven’t yet had that same career-changing moment I had with responsive design, despite the widely shared and brilliant talk that brought it to my attention. 

                                          One reason for that could be that I now work in a large organization, which is quite different from the design agency role I had in 2010. In my agency days, every new project was a clean slate, a chance to try something new. Nowadays, projects use existing tools and frameworks and are often improvements to existing websites with an existing codebase. 

                                          Another could be that I feel more prepared for change now. In 2010 I was new to design in general; the shift was frightening and required a lot of learning. Also, an intrinsic approach isn’t exactly all-new; it’s about using existing skills and existing CSS knowledge in a different way. 

                                          You can’t framework your way out of a content problem

                                          Another reason for the slightly slower adoption of intrinsic design could be the lack of quick-fix framework solutions available to kick-start the change. 

                                          Responsive grid systems were all over the place ten years ago. With a framework like Bootstrap or Skeleton, you had a responsive design template at your fingertips.

                                          Intrinsic design and frameworks do not go hand in hand quite so well because the benefit of having a selection of units is a hindrance when it comes to creating layout templates. The beauty of intrinsic design is combining different units and experimenting with techniques to get the best for your content.

                                          And then there are design tools. We probably all, at some point in our careers, used Photoshop templates for desktop, tablet, and mobile devices to drop designs in and show how the site would look at all three stages.

                                          How do you do that now, with each component responding to content and layouts flexing as and when they need to? This type of design must happen in the browser, which personally I’m a big fan of. 

                                          The debate about “whether designers should code” is another that has rumbled on for years. When designing a digital product, we should, at the very least, design for a best- and worst-case scenario when it comes to content. To do this in a graphics-based software package is far from ideal. In code, we can add longer sentences, more radio buttons, and extra tabs, and watch in real time as the design adapts. Does it still work? Is the design too reliant on the current content?

                                          Personally, I look forward to the day intrinsic design is the standard for design, when a design component can be truly flexible and adapt to both its space and content with no reliance on device or container dimensions.

                                          Content first 

                                          Content is not constant. After all, to design for the unknown or unexpected we need to account for content changes like our earlier Subgrid card example that allowed the cards to respond to adjustments to their own content and the content of sibling elements.

                                          Thankfully, there’s more to CSS than layout, and plenty of properties and values can help us put content first. Subgrid and pseudo-elements like ::first-line and ::first-letter help to separate design from markup so we can create designs that allow for changes.

                                          Instead of old markup hacks like this—

                                          <p>
                                            <span class="first-line">First line of text with different styling</span>...
                                          </p>

                                          —we can target content based on where it appears.

                                          .element::first-line {
                                            font-size: 1.4em;
                                          }
                                          
                                          .element::first-letter {
                                            color: red;
                                          }

                                          Much bigger additions to CSS include logical properties, which change the way we construct designs using logical dimensions (start and end) instead of physical ones (left and right), something CSS Grid also does with functions like min(), max(), and clamp().

                                          This flexibility allows for directional changes according to content, a common requirement when we need to present content in multiple languages. In the past, this was often achieved with Sass mixins but was often limited to switching from left-to-right to right-to-left orientation.

                                          In the Sass version, directional variables need to be set.

                                          $direction: rtl;
                                          $opposite-direction: ltr;
                                          
                                          $start-direction: right;
                                          $end-direction: left;

                                          These variables can be used as values—

                                          body {
                                            direction: $direction;
                                            text-align: $start-direction;
                                          }

                                          —or as properties.

                                          margin-#{$end-direction}: 10px;
                                          padding-#{$start-direction}: 10px;

                                          However, now we have native logical properties, removing the reliance on both Sass (or a similar tool) and pre-planning that necessitated using variables throughout a codebase. These properties also start to break apart the tight coupling between a design and strict physical dimensions, creating more flexibility for changes in language and in direction.

                                          margin-block-end: 10px;
                                          padding-block-start: 10px;

                                          There are also native start and end values for properties like text-align, which means we can replace text-align: right with text-align: start.

                                          Like the earlier examples, these properties help to build out designs that aren’t constrained to one language; the design will reflect the content’s needs.

                                          Fixed and fluid 

                                          We briefly covered the power of combining fixed widths with fluid widths with intrinsic layouts. The min() and max() functions are a similar concept, allowing you to specify a fixed value with a flexible alternative. 

                                          For min() this means setting a fluid minimum value and a maximum fixed value.

                                          .element {
                                            width: min(50%, 300px);
                                          }

                                          The element in the figure above will be 50% of its container as long as the element’s width doesn’t exceed 300px.

                                          For max() we can set a flexible max value and a minimum fixed value.

                                          .element {
                                            width: max(50%, 300px);
                                          }

                                          Now the element will be 50% of its container as long as the element’s width is at least 300px. This means we can set limits but allow content to react to the available space. 

                                          The clamp() function builds on this by allowing us to set a preferred value with a third parameter. Now we can allow the element to shrink or grow if it needs to without getting to a point where it becomes unusable.

                                          .element {
                                            width: clamp(300px, 50%, 600px);
                                          }

                                          This time, the element’s width will be 50% (the preferred value) of its container but never less than 300px and never more than 600px.

                                          With these techniques, we have a content-first approach to responsive design. We can separate content from markup, meaning the changes users make will not affect the design. We can start to future-proof designs by planning for unexpected changes in language or direction. And we can increase flexibility by setting desired dimensions alongside flexible alternatives, allowing for more or less content to be displayed correctly.

                                          Situation first

                                          Thanks to what we’ve discussed so far, we can cover device flexibility by changing our approach, designing around content and space instead of catering to devices. But what about that last bit of Jeffrey Zeldman’s quote, “...situations you haven’t imagined”?

                                          It’s a very different thing to design for someone seated at a desktop computer as opposed to someone using a mobile phone and moving through a crowded street in glaring sunshine. Situations and environments are hard to plan for or predict because they change as people react to their own unique challenges and tasks.

                                          This is why choice is so important. One size never fits all, so we need to design for multiple scenarios to create equal experiences for all our users.

                                          Thankfully, there is a lot we can do to provide choice.

                                          Responsible design 

                                          “There are parts of the world where mobile data is prohibitively expensive, and where there is little or no broadband infrastructure.”

                                          I Used the Web for a Day on a 50 MB Budget

                                          Chris Ashton

                                          One of the biggest assumptions we make is that people interacting with our designs have a good wifi connection and a wide screen monitor. But in the real world, our users may be commuters traveling on trains or other forms of transport using smaller mobile devices that can experience drops in connectivity. There is nothing more frustrating than a web page that won’t load, but there are ways we can help users use less data or deal with sporadic connectivity.

                                          The srcset attribute allows the browser to decide which image to serve. This means we can create smaller ‘cropped’ images to display on mobile devices in turn using less bandwidth and less data.

                                          <img 
                                            src="image-file.jpg"
                                            srcset="large.jpg 1024w,
                                                       medium.jpg 640w,
                                                       small.jpg 320w"
                                               alt="Image alt text" />

                                          The preload attribute can also help us to think about how and when media is downloaded. It can be used to tell a browser about any critical assets that need to be downloaded with high priority, improving perceived performance and the user experience. 

                                          <link rel="stylesheet" href="style.css"> <!--Standard stylesheet markup-->
                                          <link rel="preload" href="style.css" as="style"> <!--Preload stylesheet markup-->

                                          There’s also native lazy loading, which indicates assets that should only be downloaded when they are needed.

                                          <img src="image.png" loading="lazy" alt="…">

                                          With srcset, preload, and lazy loading, we can start to tailor a user’s experience based on the situation they find themselves in. What none of this does, however, is allow the user themselves to decide what they want downloaded, as the decision is usually the browser’s to make. 

                                          So how can we put users in control?

                                          The return of media queries 

                                          Media queries have always been about much more than device sizes. They allow content to adapt to different situations, with screen size being just one of them.

                                          We’ve long been able to check for media types like print and speech and features such as hover, resolution, and color. These checks allow us to provide options that suit more than one scenario; it’s less about one-size-fits-all and more about serving adaptable content. 

                                          As of this writing, the Media Queries Level 5 spec is still under development. It introduces some really exciting queries that in the future will help us design for multiple other unexpected situations.

                                          For example, there’s a light-level feature that allows you to modify styles if a user is in sunlight or darkness. Paired with custom properties, these features allow us to quickly create designs or themes for specific environments.

                                          @media (light-level: normal) {
                                            --background-color: #fff;
                                            --text-color: #0b0c0c;  
                                          }
                                          
                                          @media (light-level: dim) {
                                            --background-color: #efd226;
                                            --text-color: #0b0c0c;
                                          }

                                          Another key feature of the Level 5 spec is personalization. Instead of creating designs that are the same for everyone, users can choose what works for them. This is achieved by using features like prefers-reduced-data, prefers-color-scheme, and prefers-reduced-motion, the latter two of which already enjoy broad browser support. These features tap into preferences set via the operating system or browser so people don’t have to spend time making each site they visit more usable. 

                                          Media queries like this go beyond choices made by a browser to grant more control to the user.

                                          Expect the unexpected

                                          In the end, the one thing we should always expect is for things to change. Devices in particular change faster than we can keep up, with foldable screens already on the market.

                                          We can’t design the same way we have for this ever-changing landscape, but we can design for content. By putting content first and allowing that content to adapt to whatever space surrounds it, we can create more robust, flexible designs that increase the longevity of our products. 

                                          A lot of the CSS discussed here is about moving away from layouts and putting content at the heart of design. From responsive components to fixed and fluid units, there is so much more we can do to take a more intrinsic approach. Even better, we can test these techniques during the design phase by designing in-browser and watching how our designs adapt in real-time.

                                          When it comes to unexpected situations, we need to make sure our products are usable when people need them, whenever and wherever that might be. We can move closer to achieving this by involving users in our design decisions, by creating choice via browsers, and by giving control to our users with user-preference-based media queries. 

                                          Good design for the unexpected should allow for change, provide choice, and give control to those we serve: our users themselves.

                                          Asynchronous Design Critique: Getting Feedback

                                            “Any comment?” is probably one of the worst ways to ask for feedback. It’s vague and open ended, and it doesn’t provide any indication of what we’re looking for. Getting good feedback starts earlier than we might expect: it starts with the request. 

                                            It might seem counterintuitive to start the process of receiving feedback with a question, but that makes sense if we realize that getting feedback can be thought of as a form of design research. In the same way that we wouldn’t do any research without the right questions to get the insights that we need, the best way to ask for feedback is also to craft sharp questions.

                                            Design critique is not a one-shot process. Sure, any good feedback workflow continues until the project is finished, but this is particularly true for design because design work continues iteration after iteration, from a high level to the finest details. Each level needs its own set of questions.

                                            And finally, as with any good research, we need to review what we got back, get to the core of its insights, and take action. Question, iteration, and review. Let’s look at each of those.

                                            The question

                                            Being open to feedback is essential, but we need to be precise about what we’re looking for. Just saying “Any comment?”, “What do you think?”, or “I’d love to get your opinion” at the end of a presentation—whether it’s in person, over video, or through a written post—is likely to get a number of varied opinions or, even worse, get everyone to follow the direction of the first person who speaks up. And then... we get frustrated because vague questions like those can turn a high-level flows review into people instead commenting on the borders of buttons. Which might be a hearty topic, so it might be hard at that point to redirect the team to the subject that you had wanted to focus on.

                                            But how do we get into this situation? It’s a mix of factors. One is that we don’t usually consider asking as a part of the feedback process. Another is how natural it is to just leave the question implied, expecting the others to be on the same page. Another is that in nonprofessional discussions, there’s often no need to be that precise. In short, we tend to underestimate the importance of the questions, so we don’t work on improving them.

                                            The act of asking good questions guides and focuses the critique. It’s also a form of consent: it makes it clear that you’re open to comments and what kind of comments you’d like to get. It puts people in the right mental state, especially in situations when they weren’t expecting to give feedback.

                                            There isn’t a single best way to ask for feedback. It just needs to be specific, and specificity can take many shapes. A model for design critique that I’ve found particularly useful in my coaching is the one of stage versus depth.

                                            Stage” refers to each of the steps of the process—in our case, the design process. In progressing from user research to the final design, the kind of feedback evolves. But within a single step, one might still review whether some assumptions are correct and whether there’s been a proper translation of the amassed feedback into updated designs as the project has evolved. A starting point for potential questions could derive from the layers of user experience. What do you want to know: Project objectives? User needs? Functionality? Content? Interaction design? Information architecture? UI design? Navigation design? Visual design? Branding?

                                            Here’re a few example questions that are precise and to the point that refer to different layers:

                                            • Functionality: Is automating account creation desirable?
                                            • Interaction design: Take a look through the updated flow and let me know whether you see any steps or error states that I might’ve missed.
                                            • Information architecture: We have two competing bits of information on this page. Is the structure effective in communicating them both?
                                            • UI design: What are your thoughts on the error counter at the top of the page that makes sure that you see the next error, even if the error is out of the viewport? 
                                            • Navigation design: From research, we identified these second-level navigation items, but once you’re on the page, the list feels too long and hard to navigate. Are there any suggestions to address this?
                                            • Visual design: Are the sticky notifications in the bottom-right corner visible enough?

                                            The other axis of specificity is about how deep you’d like to go on what’s being presented. For example, we might have introduced a new end-to-end flow, but there was a specific view that you found particularly challenging and you’d like a detailed review of that. This can be especially useful from one iteration to the next where it’s important to highlight the parts that have changed.

                                            There are other things that we can consider when we want to achieve more specific—and more effective—questions.

                                            A simple trick is to remove generic qualifiers from your questions like “good,” “well,” “nice,” “bad,” “okay,” and “cool.” For example, asking, “When the block opens and the buttons appear, is this interaction good?” might look specific, but you can spot the “good” qualifier, and convert it to an even better question: “When the block opens and the buttons appear, is it clear what the next action is?”

                                            Sometimes we actually do want broad feedback. That’s rare, but it can happen. In that sense, you might still make it explicit that you’re looking for a wide range of opinions, whether at a high level or with details. Or maybe just say, “At first glance, what do you think?” so that it’s clear that what you’re asking is open ended but focused on someone’s impression after their first five seconds of looking at it.

                                            Sometimes the project is particularly expansive, and some areas may have already been explored in detail. In these situations, it might be useful to explicitly say that some parts are already locked in and aren’t open to feedback. It’s not something that I’d recommend in general, but I’ve found it useful to avoid falling again into rabbit holes of the sort that might lead to further refinement but aren’t what’s most important right now.

                                            Asking specific questions can completely change the quality of the feedback that you receive. People with less refined critique skills will now be able to offer more actionable feedback, and even expert designers will welcome the clarity and efficiency that comes from focusing only on what’s needed. It can save a lot of time and frustration.

                                            The iteration

                                            Design iterations are probably the most visible part of the design work, and they provide a natural checkpoint for feedback. Yet a lot of design tools with inline commenting tend to show changes as a single fluid stream in the same file, and those types of design tools make conversations disappear once they’re resolved, update shared UI components automatically, and compel designs to always show the latest version—unless these would-be helpful features were to be manually turned off. The implied goal that these design tools seem to have is to arrive at just one final copy with all discussions closed, probably because they inherited patterns from how written documents are collaboratively edited. That’s probably not the best way to approach design critiques, but even if I don’t want to be too prescriptive here: that could work for some teams.

                                            The asynchronous design-critique approach that I find most effective is to create explicit checkpoints for discussion. I’m going to use the term iteration post for this. It refers to a write-up or presentation of the design iteration followed by a discussion thread of some kind. Any platform that can accommodate this structure can use this. By the way, when I refer to a “write-up or presentation,” I’m including video recordings or other media too: as long as it’s asynchronous, it works.

                                            Using iteration posts has many advantages:

                                            • It creates a rhythm in the design work so that the designer can review feedback from each iteration and prepare for the next.
                                            • It makes decisions visible for future review, and conversations are likewise always available.
                                            • It creates a record of how the design changed over time.
                                            • Depending on the tool, it might also make it easier to collect feedback and act on it.

                                            These posts of course don’t mean that no other feedback approach should be used, just that iteration posts could be the primary rhythm for a remote design team to use. And other feedback approaches (such as live critique, pair designing, or inline comments) can build from there.

                                            I don’t think there’s a standard format for iteration posts. But there are a few high-level elements that make sense to include as a baseline:

                                            1. The goal
                                            2. The design
                                            3. The list of changes
                                            4. The questions

                                            Each project is likely to have a goal, and hopefully it’s something that’s already been summarized in a single sentence somewhere else, such as the client brief, the product manager’s outline, or the project owner’s request. So this is something that I’d repeat in every iteration post—literally copy and pasting it. The idea is to provide context and to repeat what’s essential to make each iteration post complete so that there’s no need to find information spread across multiple posts. If I want to know about the latest design, the latest iteration post will have all that I need.

                                            This copy-and-paste part introduces another relevant concept: alignment comes from repetition. So having posts that repeat information is actually very effective toward making sure that everyone is on the same page.

                                            The design is then the actual series of information-architecture outlines, diagrams, flows, maps, wireframes, screens, visuals, and any other kind of design work that’s been done. In short, it’s any design artifact. For the final stages of work, I prefer the term blueprint to emphasize that I’ll be showing full flows instead of individual screens to make it easier to understand the bigger picture. 

                                            It can also be useful to label the artifacts with clear titles because that can make it easier to refer to them. Write the post in a way that helps people understand the work. It’s not too different from organizing a good live presentation. 

                                            For an efficient discussion, you should also include a bullet list of the changes from the previous iteration to let people focus on what’s new, which can be especially useful for larger pieces of work where keeping track, iteration after iteration, could become a challenge.

                                            And finally, as noted earlier, it’s essential that you include a list of the questions to drive the design critique in the direction you want. Doing this as a numbered list can also help make it easier to refer to each question by its number.

                                            Not all iterations are the same. Earlier iterations don’t need to be as tightly focused—they can be more exploratory and experimental, maybe even breaking some of the design-language guidelines to see what’s possible. Then later, the iterations start settling on a solution and refining it until the design process reaches its end and the feature ships.

                                            I want to highlight that even if these iteration posts are written and conceived as checkpoints, by no means do they need to be exhaustive. A post might be a draft—just a concept to get a conversation going—or it could be a cumulative list of each feature that was added over the course of each iteration until the full picture is done.

                                            Over time, I also started using specific labels for incremental iterations: i1, i2, i3, and so on. This might look like a minor labelling tip, but it can help in multiple ways:

                                            • Unique—It’s a clear unique marker. Within each project, one can easily say, “This was discussed in i4,” and everyone knows where they can go to review things.
                                            • Unassuming—It works like versions (such as v1, v2, and v3) but in contrast, versions create the impression of something that’s big, exhaustive, and complete. Iterations must be able to be exploratory, incomplete, partial.
                                            • Future proof—It resolves the “final” naming problem that you can run into with versions. No more files named “final final complete no-really-its-done.” Within each project, the largest number always represents the latest iteration.

                                            To mark when a design is complete enough to be worked on, even if there might be some bits still in need of attention and in turn more iterations needed, the wording release candidate (RC) could be used to describe it: “with i8, we reached RC” or “i12 is an RC.”

                                            The review

                                            What usually happens during a design critique is an open discussion, with a back and forth between people that can be very productive. This approach is particularly effective during live, synchronous feedback. But when we work asynchronously, it’s more effective to use a different approach: we can shift to a user-research mindset. Written feedback from teammates, stakeholders, or others can be treated as if it were the result of user interviews and surveys, and we can analyze it accordingly.

                                            This shift has some major benefits that make asynchronous feedback particularly effective, especially around these friction points:

                                            1. It removes the pressure to reply to everyone.
                                            2. It reduces the frustration from swoop-by comments.
                                            3. It lessens our personal stake.

                                            The first friction point is feeling a pressure to reply to every single comment. Sometimes we write the iteration post, and we get replies from our team. It’s just a few of them, it’s easy, and it doesn’t feel like a problem. But other times, some solutions might require more in-depth discussions, and the amount of replies can quickly increase, which can create a tension between trying to be a good team player by replying to everyone and doing the next design iteration. This might be especially true if the person who’s replying is a stakeholder or someone directly involved in the project who we feel that we need to listen to. We need to accept that this pressure is absolutely normal, and it’s human nature to try to accommodate people who we care about. Sometimes replying to all comments can be effective, but if we treat a design critique more like user research, we realize that we don’t have to reply to every comment, and in asynchronous spaces, there are alternatives:

                                            • One is to let the next iteration speak for itself. When the design evolves and we post a follow-up iteration, that’s the reply. You might tag all the people who were involved in the previous discussion, but even that’s a choice, not a requirement. 
                                            • Another is to briefly reply to acknowledge each comment, such as “Understood. Thank you,” “Good points—I’ll review,” or “Thanks. I’ll include these in the next iteration.” In some cases, this could also be just a single top-level comment along the lines of “Thanks for all the feedback everyone—the next iteration is coming soon!”
                                            • Another is to provide a quick summary of the comments before moving on. Depending on your workflow, this can be particularly useful as it can provide a simplified checklist that you can then use for the next iteration.

                                            The second friction point is the swoop-by comment, which is the kind of feedback that comes from someone outside the project or team who might not be aware of the context, restrictions, decisions, or requirements—or of the previous iterations’ discussions. On their side, there’s something that one can hope that they might learn: they could start to acknowledge that they’re doing this and they could be more conscious in outlining where they’re coming from. Swoop-by comments often trigger the simple thought “We’ve already discussed this…”, and it can be frustrating to have to repeat the same reply over and over.

                                            Let’s begin by acknowledging again that there’s no need to reply to every comment. If, however, replying to a previously litigated point might be useful, a short reply with a link to the previous discussion for extra details is usually enough. Remember, alignment comes from repetition, so it’s okay to repeat things sometimes!

                                            Swoop-by commenting can still be useful for two reasons: they might point out something that still isn’t clear, and they also have the potential to stand in for the point of view of a user who’s seeing the design for the first time. Sure, you’ll still be frustrated, but that might at least help in dealing with it.

                                            The third friction point is the personal stake we could have with the design, which could make us feel defensive if the review were to feel more like a discussion. Treating feedback as user research helps us create a healthy distance between the people giving us feedback and our ego (because yes, even if we don’t want to admit it, it’s there). And ultimately, treating everything in aggregated form allows us to better prioritize our work.

                                            Always remember that while you need to listen to stakeholders, project owners, and specific advice, you don’t have to accept every piece of feedback. You have to analyze it and make a decision that you can justify, but sometimes “no” is the right answer. 

                                            As the designer leading the project, you’re in charge of that decision. Ultimately, everyone has their specialty, and as the designer, you’re the one who has the most knowledge and the most context to make the right decision. And by listening to the feedback that you’ve received, you’re making sure that it’s also the best and most balanced decision.

                                            Thanks to Brie Anne Demkiw and Mike Shelton for reviewing the first draft of this article.

                                            Asynchronous Design Critique: Giving Feedback

                                              Feedback, in whichever form it takes, and whatever it may be called, is one of the most effective soft skills that we have at our disposal to collaboratively get our designs to a better place while growing our own skills and perspectives.

                                              Feedback is also one of the most underestimated tools, and often by assuming that we’re already good at it, we settle, forgetting that it’s a skill that can be trained, grown, and improved. Poor feedback can create confusion in projects, bring down morale, and affect trust and team collaboration over the long term. Quality feedback can be a transformative force. 

                                              Practicing our skills is surely a good way to improve, but the learning gets even faster when it’s paired with a good foundation that channels and focuses the practice. What are some foundational aspects of giving good feedback? And how can feedback be adjusted for remote and distributed work environments? 

                                              On the web, we can identify a long tradition of asynchronous feedback: from the early days of open source, code was shared and discussed on mailing lists. Today, developers engage on pull requests, designers comment in their favorite design tools, project managers and scrum masters exchange ideas on tickets, and so on.

                                              Design critique is often the name used for a type of feedback that’s provided to make our work better, collaboratively. So it shares a lot of the principles with feedback in general, but it also has some differences.

                                              The content

                                              The foundation of every good critique is the feedback’s content, so that’s where we need to start. There are many models that you can use to shape your content. The one that I personally like best—because it’s clear and actionable—is this one from Lara Hogan.

                                              While this equation is generally used to give feedback to people, it also fits really well in a design critique because it ultimately answers some of the core questions that we work on: What? Where? Why? How? Imagine that you’re giving some feedback about some design work that spans multiple screens, like an onboarding flow: there are some pages shown, a flow blueprint, and an outline of the decisions made. You spot something that could be improved. If you keep the three elements of the equation in mind, you’ll have a mental model that can help you be more precise and effective.

                                              Here is a comment that could be given as a part of some feedback, and it might look reasonable at a first glance: it seems to superficially fulfill the elements in the equation. But does it?

                                              Not sure about the buttons’ styles and hierarchy—it feels off. Can you change them?

                                              Observation for design feedback doesn’t just mean pointing out which part of the interface your feedback refers to, but it also refers to offering a perspective that’s as specific as possible. Are you providing the user’s perspective? Your expert perspective? A business perspective? The project manager’s perspective? A first-time user’s perspective?

                                              When I see these two buttons, I expect one to go forward and one to go back.

                                              Impact is about the why. Just pointing out a UI element might sometimes be enough if the issue may be obvious, but more often than not, you should add an explanation of what you’re pointing out.

                                              When I see these two buttons, I expect one to go forward and one to go back. But this is the only screen where this happens, as before we just used a single button and an “×” to close. This seems to be breaking the consistency in the flow.

                                              The question approach is meant to provide open guidance by eliciting the critical thinking in the designer receiving the feedback. Notably, in Lara’s equation she provides a second approach: request, which instead provides guidance toward a specific solution. While that’s a viable option for feedback in general, for design critiques, in my experience, defaulting to the question approach usually reaches the best solutions because designers are generally more comfortable in being given an open space to explore.

                                              The difference between the two can be exemplified with, for the question approach:

                                              When I see these two buttons, I expect one to go forward and one to go back. But this is the only screen where this happens, as before we just used a single button and an “×” to close. This seems to be breaking the consistency in the flow. Would it make sense to unify them?

                                              Or, for the request approach:

                                              When I see these two buttons, I expect one to go forward and one to go back. But this is the only screen where this happens, as before we just used a single button and an “×” to close. This seems to be breaking the consistency in the flow. Let’s make sure that all screens have the same pair of forward and back buttons.

                                              At this point in some situations, it might be useful to integrate with an extra why: why you consider the given suggestion to be better.

                                              When I see these two buttons, I expect one to go forward and one to go back. But this is the only screen where this happens, as before we just used a single button and an “×” to close. This seems to be breaking the consistency in the flow. Let’s make sure that all screens have the same two forward and back buttons so that users don’t get confused.

                                              Choosing the question approach or the request approach can also at times be a matter of personal preference. A while ago, I was putting a lot of effort into improving my feedback: I did rounds of anonymous feedback, and I reviewed feedback with other people. After a few rounds of this work and a year later, I got a positive response: my feedback came across as effective and grounded. Until I changed teams. To my shock, my next round of feedback from one specific person wasn’t that great. The reason is that I had previously tried not to be prescriptive in my advice—because the people who I was previously working with preferred the open-ended question format over the request style of suggestions. But now in this other team, there was one person who instead preferred specific guidance. So I adapted my feedback for them to include requests.

                                              One comment that I heard come up a few times is that this kind of feedback is quite long, and it doesn’t seem very efficient. No… but also yes. Let’s explore both sides.

                                              No, this style of feedback is actually efficient because the length here is a byproduct of clarity, and spending time giving this kind of feedback can provide exactly enough information for a good fix. Also if we zoom out, it can reduce future back-and-forth conversations and misunderstandings, improving the overall efficiency and effectiveness of collaboration beyond the single comment. Imagine that in the example above the feedback were instead just, “Let’s make sure that all screens have the same two forward and back buttons.” The designer receiving this feedback wouldn’t have much to go by, so they might just apply the change. In later iterations, the interface might change or they might introduce new features—and maybe that change might not make sense anymore. Without the why, the designer might imagine that the change is about consistency… but what if it wasn’t? So there could now be an underlying concern that changing the buttons would be perceived as a regression.

                                              Yes, this style of feedback is not always efficient because the points in some comments don’t always need to be exhaustive, sometimes because certain changes may be obvious (“The font used doesn’t follow our guidelines”) and sometimes because the team may have a lot of internal knowledge such that some of the whys may be implied.

                                              So the equation above isn’t meant to suggest a strict template for feedback but a mnemonic to reflect and improve the practice. Even after years of active work on my critiques, I still from time to time go back to this formula and reflect on whether what I just wrote is effective.

                                              The tone

                                              Well-grounded content is the foundation of feedback, but that’s not really enough. The soft skills of the person who’s providing the critique can multiply the likelihood that the feedback will be well received and understood. Tone alone can make the difference between content that’s rejected or welcomed, and it’s been demonstrated that only positive feedback creates sustained change in people.

                                              Since our goal is to be understood and to have a positive working environment, tone is essential to work on. Over the years, I’ve tried to summarize the required soft skills in a formula that mirrors the one for content: the receptivity equation.

                                              Respectful feedback comes across as grounded, solid, and constructive. It’s the kind of feedback that, whether it’s positive or negative, is perceived as useful and fair.

                                              Timing refers to when the feedback happens. To-the-point feedback doesn’t have much hope of being well received if it’s given at the wrong time. Questioning the entire high-level information architecture of a new feature when it’s about to ship might still be relevant if that questioning highlights a major blocker that nobody saw, but it’s way more likely that those concerns will have to wait for a later rework. So in general, attune your feedback to the stage of the project. Early iteration? Late iteration? Polishing work in progress? These all have different needs. The right timing will make it more likely that your feedback will be well received.

                                              Attitude is the equivalent of intent, and in the context of person-to-person feedback, it can be referred to as radical candor. That means checking before we write to see whether what we have in mind will truly help the person and make the project better overall. This might be a hard reflection at times because maybe we don’t want to admit that we don’t really appreciate that person. Hopefully that’s not the case, but that can happen, and that’s okay. Acknowledging and owning that can help you make up for that: how would I write if I really cared about them? How can I avoid being passive aggressive? How can I be more constructive?

                                              Form is relevant especially in a diverse and cross-cultural work environments because having great content, perfect timing, and the right attitude might not come across if the way that we write creates misunderstandings. There might be many reasons for this: sometimes certain words might trigger specific reactions; sometimes nonnative speakers might not understand all the nuances of some sentences; sometimes our brains might just be different and we might perceive the world differently—neurodiversity must be taken into consideration. Whatever the reason, it’s important to review not just what we write but how.

                                              A few years back, I was asking for some feedback on how I give feedback. I received some good advice but also a comment that surprised me. They pointed out that when I wrote “Oh, […],” I made them feel stupid. That wasn’t my intent! I felt really bad, and I just realized that I provided feedback to them for months, and every time I might have made them feel stupid. I was horrified… but also thankful. I made a quick fix: I added “oh” in my list of replaced words (your choice between: macOS’s text replacement, aText, TextExpander, or others) so that when I typed “oh,” it was instantly deleted. 

                                              Something to highlight because it’s quite frequent—especially in teams that have a strong group spirit—is that people tend to beat around the bush. It’s important to remember here that a positive attitude doesn’t mean going light on the feedback—it just means that even when you provide hard, difficult, or challenging feedback, you do so in a way that’s respectful and constructive. The nicest thing that you can do for someone is to help them grow.

                                              We have a great advantage in giving feedback in written form: it can be reviewed by another person who isn’t directly involved, which can help to reduce or remove any bias that might be there. I found that the best, most insightful moments for me have happened when I’ve shared a comment and I’ve asked someone who I highly trusted, “How does this sound?,” “How can I do it better,” and even “How would you have written it?”—and I’ve learned a lot by seeing the two versions side by side.

                                              The format

                                              Asynchronous feedback also has a major inherent advantage: we can take more time to refine what we’ve written to make sure that it fulfills two main goals: the clarity of communication and the actionability of the suggestions.

                                              Let’s imagine that someone shared a design iteration for a project. You are reviewing it and leaving a comment. There are many ways to do this, and of course context matters, but let’s try to think about some elements that may be useful to consider.

                                              In terms of clarity, start by grounding the critique that you’re about to give by providing context. Specifically, this means describing where you’re coming from: do you have a deep knowledge of the project, or is this the first time that you’re seeing it? Are you coming from a high-level perspective, or are you figuring out the details? Are there regressions? Which user’s perspective are you taking when providing your feedback? Is the design iteration at a point where it would be okay to ship this, or are there major things that need to be addressed first?

                                              Providing context is helpful even if you’re sharing feedback within a team that already has some information on the project. And context is absolutely essential when giving cross-team feedback. If I were to review a design that might be indirectly related to my work, and if I had no knowledge about how the project arrived at that point, I would say so, highlighting my take as external.

                                              We often focus on the negatives, trying to outline all the things that could be done better. That’s of course important, but it’s just as important—if not more—to focus on the positives, especially if you saw progress from the previous iteration. This might seem superfluous, but it’s important to keep in mind that design is a discipline where there are hundreds of possible solutions for every problem. So pointing out that the design solution that was chosen is good and explaining why it’s good has two major benefits: it confirms that the approach taken was solid, and it helps to ground your negative feedback. In the longer term, sharing positive feedback can help prevent regressions on things that are going well because those things will have been highlighted as important. As a bonus, positive feedback can also help reduce impostor syndrome.

                                              There’s one powerful approach that combines both context and a focus on the positives: frame how the design is better than the status quo (compared to a previous iteration, competitors, or benchmarks) and why, and then on that foundation, you can add what could be improved. This is powerful because there’s a big difference between a critique that’s for a design that’s already in good shape and a critique that’s for a design that isn’t quite there yet.

                                              Another way that you can improve your feedback is to depersonalize the feedback: the comments should always be about the work, never about the person who made it. It’s “This button isn’t well aligned” versus “You haven’t aligned this button well.” This is very easy to change in your writing by reviewing it just before sending.

                                              In terms of actionability, one of the best approaches to help the designer who’s reading through your feedback is to split it into bullet points or paragraphs, which are easier to review and analyze one by one. For longer pieces of feedback, you might also consider splitting it into sections or even across multiple comments. Of course, adding screenshots or signifying markers of the specific part of the interface you’re referring to can also be especially useful.

                                              One approach that I’ve personally used effectively in some contexts is to enhance the bullet points with four markers using emojis. So a red square 🟥 means that it’s something that I consider blocking; a yellow diamond 🔶 is something that I can be convinced otherwise, but it seems to me that it should be changed; and a green circle 🟢 is a detailed, positive confirmation. I also use a blue spiral 🌀 for either something that I’m not sure about, an exploration, an open alternative, or just a note. But I’d use this approach only on teams where I’ve already established a good level of trust because if it happens that I have to deliver a lot of red squares, the impact could be quite demoralizing, and I’d reframe how I’d communicate that a bit.

                                              Let’s see how this would work by reusing the example that we used earlier as the first bullet point in this list:

                                              • 🔶 Navigation—When I see these two buttons, I expect one to go forward and one to go back. But this is the only screen where this happens, as before we just used a single button and an “×” to close. This seems to be breaking the consistency in the flow. Let’s make sure that all screens have the same two forward and back buttons so that users don’t get confused.
                                              • 🟢 Overall—I think the page is solid, and this is good enough to be our release candidate for a version 1.0.
                                              • 🟢 Metrics—Good improvement in the buttons on the metrics area; the improved contrast and new focus style make them more accessible.
                                              •  🟥  Button Style—Using the green accent in this context creates the impression that it’s a positive action because green is usually perceived as a confirmation color. Do we need to explore a different color?
                                              • 🔶Tiles—Given the number of items on the page, and the overall page hierarchy, it seems to me that the tiles shouldn’t be using the Subtitle 1 style but the Subtitle 2 style. This will keep the visual hierarchy more consistent.
                                              • 🌀 Background—Using a light texture works well, but I wonder whether it adds too much noise in this kind of page. What is the thinking in using that?

                                              What about giving feedback directly in Figma or another design tool that allows in-place feedback? In general, I find these difficult to use because they hide discussions and they’re harder to track, but in the right context, they can be very effective. Just make sure that each of the comments is separate so that it’s easier to match each discussion to a single task, similar to the idea of splitting mentioned above.

                                              One final note: say the obvious. Sometimes we might feel that something is obviously good or obviously wrong, and so we don’t say it. Or sometimes we might have a doubt that we don’t express because the question might sound stupid. Say it—that’s okay. You might have to reword it a little bit to make the reader feel more comfortable, but don’t hold it back. Good feedback is transparent, even when it may be obvious.

                                              There’s another advantage of asynchronous feedback: written feedback automatically tracks decisions. Especially in large projects, “Why did we do this?” could be a question that pops up from time to time, and there’s nothing better than open, transparent discussions that can be reviewed at any time. For this reason, I recommend using software that saves these discussions, without hiding them once they are resolved. 

                                              Content, tone, and format. Each one of these subjects provides a useful model, but working to improve eight areas—observation, impact, question, timing, attitude, form, clarity, and actionability—is a lot of work to put in all at once. One effective approach is to take them one by one: first identify the area that you lack the most (either from your perspective or from feedback from others) and start there. Then the second, then the third, and so on. At first you’ll have to put in extra time for every piece of feedback that you give, but after a while, it’ll become second nature, and your impact on the work will multiply.

                                              Thanks to Brie Anne Demkiw and Mike Shelton for reviewing the first draft of this article.

                                              That’s Not My Burnout

                                                Are you like me, reading about people fading away as they burn out, and feeling unable to relate? Do you feel like your feelings are invisible to the world because you’re experiencing burnout differently? When burnout starts to push down on us, our core comes through more. Beautiful, peaceful souls get quieter and fade into that distant and distracted burnout we’ve all read about. But some of us, those with fires always burning on the edges of our core, get hotter. In my heart I am fire. When I face burnout I double down, triple down, burning hotter and hotter to try to best the challenge. I don’t fade—I am engulfed in a zealous burnout

                                                So what on earth is a zealous burnout?

                                                Imagine a woman determined to do it all. She has two amazing children whom she, along with her husband who is also working remotely, is homeschooling during a pandemic. She has a demanding client load at work—all of whom she loves. She gets up early to get some movement in (or often catch up on work), does dinner prep as the kids are eating breakfast, and gets to work while positioning herself near “fourth grade” to listen in as she juggles clients, tasks, and budgets. Sound like a lot? Even with a supportive team both at home and at work, it is. 

                                                Sounds like this woman has too much on her plate and needs self-care. But no, she doesn’t have time for that. In fact, she starts to feel like she’s dropping balls. Not accomplishing enough. There’s not enough of her to be here and there; she is trying to divide her mind in two all the time, all day, every day. She starts to doubt herself. And as those feelings creep in more and more, her internal narrative becomes more and more critical.

                                                Suddenly she KNOWS what she needs to do! She should DO MORE. 

                                                This is a hard and dangerous cycle. Know why? Because once she doesn’t finish that new goal, that narrative will get worse. Suddenly she’s failing. She isn’t doing enough. SHE is not enough. She might fail, she might fail her family...so she’ll find more she should do. She doesn’t sleep as much, move as much, all in the efforts to do more. Caught in this cycle of trying to prove herself to herself, never reaching any goal. Never feeling “enough.” 

                                                So, yeah, that’s what zealous burnout looks like for me. It doesn’t happen overnight in some grand gesture but instead slowly builds over weeks and months. My burning out process looks like speeding up, not a person losing focus. I speed up and up and up...and then I just stop.

                                                I am the one who could

                                                It’s funny the things that shape us. Through the lens of childhood, I viewed the fears, struggles, and sacrifices of someone who had to make it all work without having enough. I was lucky that my mother was so resourceful and my father supportive; I never went without and even got an extra here or there. 

                                                Growing up, I did not feel shame when my mother paid with food stamps; in fact, I’d have likely taken on any debate on the topic, verbally eviscerating anyone who dared to criticize the disabled woman trying to make sure all our needs were met with so little. As a child, I watched the way the fear of not making those ends meet impacted people I love. As the non-disabled person in my home, I would take on many of the physical tasks because I was “the one who could” make our lives a little easier. I learned early to associate fears or uncertainty with putting more of myself into it—I am the one who can. I learned early that when something frightens me, I can double down and work harder to make it better. I can own the challenge. When people have seen this in me as an adult, I’ve been told I seem fearless, but make no mistake, I’m not. If I seem fearless, it’s because this behavior was forged from other people’s fears. 

                                                And here I am, more than 30 years later still feeling the urge to mindlessly push myself forward when faced with overwhelming tasks ahead of me, assuming that I am the one who can and therefore should. I find myself driven to prove that I can make things happen if I work longer hours, take on more responsibility, and do more

                                                I do not see people who struggle financially as failures, because I have seen how strong that tide can be—it pulls you along the way. I truly get that I have been privileged to be able to avoid many of the challenges that were present in my youth. That said, I am still “the one who can” who feels she should, so if I were faced with not having enough to make ends meet for my own family, I would see myself as having failed. Though I am supported and educated, most of this is due to good fortune. I will, however, allow myself the arrogance of saying I have been careful with my choices to have encouraged that luck. My identity stems from the idea that I am “the one who can” so therefore feel obligated to do the most. I can choose to stop, and with some quite literal cold water splashed in my face, I’ve made the choice to before. But that choosing to stop is not my go-to; I move forward, driven by a fear that is so a part of me that I barely notice it’s there until I’m feeling utterly worn away.

                                                So why all the history? You see, burnout is a fickle thing. I have heard and read a lot about burnout over the years. Burnout is real. Especially now, with COVID, many of us are balancing more than we ever have before—all at once! It’s hard, and the procrastinating, the avoidance, the shutting down impacts so many amazing professionals. There are important articles that relate to what I imagine must be the majority of people out there, but not me. That’s not what my burnout looks like.

                                                The dangerous invisibility of zealous burnout

                                                A lot of work environments see the extra hours, extra effort, and overall focused commitment as an asset (and sometimes that’s all it is). They see someone trying to rise to challenges, not someone stuck in their fear. Many well-meaning organizations have safeguards in place to protect their teams from burnout. But in cases like this, those alarms are not always tripped, and then when the inevitable stop comes, some members of the organization feel surprised and disappointed. And sometimes maybe even betrayed. 

                                                Parents—more so mothers, statistically speaking—are praised as being so on top of it all when they can work, be involved in the after-school activities, practice self-care in the form of diet and exercise, and still meet friends for coffee or wine. During COVID many of us have binged countless streaming episodes showing how it’s so hard for the female protagonist, but she is strong and funny and can do it. It’s a “very special episode” when she breaks down, cries in the bathroom, woefully admits she needs help, and just stops for a bit. Truth is, countless people are hiding their tears or are doom-scrolling to escape. We know that the media is a lie to amuse us, but often the perception that it’s what we should strive for has penetrated much of society.

                                                Women and burnout

                                                I love men. And though I don’t love every man (heads up, I don’t love every woman or nonbinary person either), I think there is a beautiful spectrum of individuals who represent that particular binary gender. 

                                                That said, women are still more often at risk of burnout than their male counterparts, especially in these COVID stressed times. Mothers in the workplace feel the pressure to do all the “mom” things while giving 110%. Mothers not in the workplace feel they need to do more to “justify” their lack of traditional employment. Women who are not mothers often feel the need to do even more because they don’t have that extra pressure at home. It’s vicious and systemic and so a part of our culture that we’re often not even aware of the enormity of the pressures we put on ourselves and each other. 

                                                And there are prices beyond happiness too. Harvard Health Publishing released a study a decade ago that “uncovered strong links between women’s job stress and cardiovascular disease.” The CDC noted, “Heart disease is the leading cause of death for women in the United States, killing 299,578 women in 2017—or about 1 in every 5 female deaths.” 

                                                This relationship between work stress and health, from what I have read, is more dangerous for women than it is for their non-female counterparts.

                                                But what if your burnout isn’t like that either?

                                                That might not be you either. After all, each of us is so different and how we respond to stressors is too. It’s part of what makes us human. Don’t stress what burnout looks like, just learn to recognize it in yourself. Here are a few questions I sometimes ask friends if I am concerned about them.

                                                Are you happy? This simple question should be the first thing you ask yourself. Chances are, even if you’re burning out doing all the things you love, as you approach burnout you’ll just stop taking as much joy from it all.

                                                Do you feel empowered to say no? I have observed in myself and others that when someone is burning out, they no longer feel they can say no to things. Even those who don’t “speed up” feel pressure to say yes to not disappoint the people around them.

                                                What are three things you’ve done for yourself? Another observance is that we all tend to stop doing things for ourselves. Anything from skipping showers and eating poorly to avoiding talking to friends. These can be red flags. 

                                                Are you making excuses? Many of us try to disregard feelings of burnout. Over and over I have heard, “It’s just crunch time,” “As soon as I do this one thing, it will all be better,” and “Well I should be able to handle this, so I’ll figure it out.” And it might really be crunch time, a single goal, and/or a skill set you need to learn. That happens—life happens. BUT if this doesn’t stop, be honest with yourself. If you’ve worked more 50-hour weeks since January than not, maybe it’s not crunch time—maybe it’s a bad situation that you’re burning out from.

                                                Do you have a plan to stop feeling this way? If something is truly temporary and you do need to just push through, then it has an exit route with a
                                                defined end.

                                                Take the time to listen to yourself as you would a friend. Be honest, allow yourself to be uncomfortable, and break the thought cycles that prevent you from healing. 

                                                So now what?

                                                What I just described is a different path to burnout, but it’s still burnout. There are well-established approaches to working through burnout:

                                                • Get enough sleep.
                                                • Eat healthy.
                                                • Work out.
                                                • Get outside.
                                                • Take a break.
                                                • Overall, practice self-care.

                                                Those are hard for me because they feel like more tasks. If I’m in the burnout cycle, doing any of the above for me feels like a waste. The narrative is that if I’m already failing, why would I take care of myself when I’m dropping all those other balls? People need me, right? 

                                                If you’re deep in the cycle, your inner voice might be pretty awful by now. If you need to, tell yourself you need to take care of the person your people depend on. If your roles are pushing you toward burnout, use them to help make healing easier by justifying the time spent working on you. 

                                                To help remind myself of the airline attendant message about putting the mask on yourself first, I have come up with a few things that I do when I start feeling myself going into a zealous burnout.

                                                Cook an elaborate meal for someone! 

                                                OK, I am a “food-focused” individual so cooking for someone is always my go-to. There are countless tales in my home of someone walking into the kitchen and turning right around and walking out when they noticed I was “chopping angrily.” But it’s more than that, and you should give it a try. Seriously. It’s the perfect go-to if you don’t feel worthy of taking time for yourself—do it for someone else. Most of us work in a digital world, so cooking can fill all of your senses and force you to be in the moment with all the ways you perceive the world. It can break you out of your head and help you gain a better perspective. In my house, I’ve been known to pick a place on the map and cook food that comes from wherever that is (thank you, Pinterest). I love cooking Indian food, as the smells are warm, the bread needs just enough kneading to keep my hands busy, and the process takes real attention for me because it’s not what I was brought up making. And in the end, we all win!

                                                Vent like a foul-mouthed fool

                                                Be careful with this one! 

                                                I have been making an effort to practice more gratitude over the past few years, and I recognize the true benefits of that. That said, sometimes you just gotta let it all out—even the ugly. Hell, I’m a big fan of not sugarcoating our lives, and that sometimes means that to get past the big pile of poop, you’re gonna wanna complain about it a bit. 

                                                When that is what’s needed, turn to a trusted friend and allow yourself some pure verbal diarrhea, saying all the things that are bothering you. You need to trust this friend not to judge, to see your pain, and, most importantly, to tell you to remove your cranium from your own rectal cavity. Seriously, it’s about getting a reality check here! One of the things I admire the most about my husband (though often after the fact) is his ability to break things down to their simplest. “We’re spending our lives together, of course you’re going to disappoint me from time to time, so get over it” has been his way of speaking his dedication, love, and acceptance of me—and I could not be more grateful. It also, of course, has meant that I needed to remove my head from that rectal cavity. So, again, usually those moments are appreciated in hindsight.

                                                Pick up a book! 

                                                There are many books out there that aren’t so much self-help as they are people just like you sharing their stories and how they’ve come to find greater balance. Maybe you’ll find something that speaks to you. Titles that have stood out to me include:

                                                • Thrive by Arianna Huffington
                                                • Tools of Titans by Tim Ferriss
                                                • Girl, Stop Apologizing by Rachel Hollis
                                                • Dare to Lead by Brené Brown

                                                Or, another tactic I love to employ is to read or listen to a book that has NOTHING to do with my work-life balance. I’ve read the following books and found they helped balance me out because my mind was pondering their interesting topics instead of running in circles:

                                                • The Drunken Botanist by Amy Stewart
                                                • Superlife by Darin Olien
                                                • A Brief History of Everyone Who Ever Lived by Adam Rutherford
                                                • Gaia’s Garden by Toby Hemenway 

                                                If you’re not into reading, pick up a topic on YouTube or choose a podcast to subscribe to. I’ve watched countless permaculture and gardening topics in addition to how to raise chickens and ducks. For the record, I do not have a particularly large food garden, nor do I own livestock of any kind...yet. I just find the topic interesting, and it has nothing to do with any aspect of my life that needs anything from me.

                                                Forgive yourself 

                                                You are never going to be perfect—hell, it would be boring if you were. It’s OK to be broken and flawed. It’s human to be tired and sad and worried. It’s OK to not do it all. It’s scary to be imperfect, but you cannot be brave if nothing were scary.

                                                This last one is the most important: allow yourself permission to NOT do it all. You never promised to be everything to everyone at all times. We are more powerful than the fears that drive us. 

                                                This is hard. It is hard for me. It’s what’s driven me to write this—that it’s OK to stop. It’s OK that your unhealthy habit that might even benefit those around you needs to end. You can still be successful in life.

                                                I recently read that we are all writing our eulogy in how we live. Knowing that your professional accomplishments won’t be mentioned in that speech, what will yours say? What do you want it to say? 

                                                Look, I get that none of these ideas will “fix it,” and that’s not their purpose. None of us are in control of our surroundings, only how we respond to them. These suggestions are to help stop the spiral effect so that you are empowered to address the underlying issues and choose your response. They are things that work for me most of the time. Maybe they’ll work for you.

                                                Does this sound familiar? 

                                                If this sounds familiar, it’s not just you. Don’t let your negative self-talk tell you that you “even burn out wrong.” It’s not wrong. Even if rooted in fear like my own drivers, I believe that this need to do more comes from a place of love, determination, motivation, and other wonderful attributes that make you the amazing person you are. We’re going to be OK, ya know. The lives that unfold before us might never look like that story in our head—that idea of “perfect” or “done” we’re looking for, but that’s OK. Really, when we stop and look around, usually the only eyes that judge us are in the mirror. 

                                                Do you remember that Winnie the Pooh sketch that had Pooh eat so much at Rabbit’s house that his buttocks couldn’t fit through the door? Well, I already associate a lot with Rabbit, so it came as no surprise when he abruptly declared that this was unacceptable. But do you recall what happened next? He put a shelf across poor Pooh’s ankles and decorations on his back, and made the best of the big butt in his kitchen. 

                                                At the end of the day we are resourceful and know that we are able to push ourselves if we need to—even when we are tired to our core or have a big butt of fluff ‘n’ stuff in our room. None of us has to be afraid, as we can manage any obstacle put in front of us. And maybe that means we will need to redefine success to allow space for being uncomfortably human, but that doesn’t really sound so bad either. 

                                                So, wherever you are right now, please breathe. Do what you need to do to get out of your head. Forgive and take care.

                                                Beware the Cut ‘n’ Paste Persona

                                                  This Person Does Not Exist is a website that generates human faces with a machine learning algorithm. It takes real portraits and recombines them into fake human faces. We recently scrolled past a LinkedIn post stating that this website could be useful “if you are developing a persona and looking for a photo.” 

                                                  We agree: the computer-generated faces could be a great match for personas—but not for the reason you might think. Ironically, the website highlights the core issue of this very common design method: the person(a) does not exist. Like the pictures, personas are artificially made. Information is taken out of natural context and recombined into an isolated snapshot that’s detached from reality. 

                                                  But strangely enough, designers use personas to inspire their design for the real world. 

                                                  Personas: A step back

                                                  Most designers have created, used, or come across personas at least once in their career. In their article “Personas - A Simple Introduction,” the Interaction Design Foundation defines personas as “fictional characters, which you create based upon your research in order to represent the different user types that might use your service, product, site, or brand.” In their most complete expression, personas typically consist of a name, profile picture, quotes, demographics, goals, needs, behavior in relation to a certain service/product, emotions, and motivations (for example, see Creative Companion’s Persona Core Poster). The purpose of personas, as stated by design agency Designit, is “to make the research relatable, [and] easy to communicate, digest, reference, and apply to product and service development.”

                                                  The decontextualization of personas

                                                  Personas are popular because they make “dry” research data more relatable, more human. However, this method constrains the researcher’s data analysis in such a way that the investigated users are removed from their unique contexts. As a result, personas don’t portray key factors that make you understand their decision-making process or allow you to relate to users’ thoughts and behavior; they lack stories. You understand what the persona did, but you don’t have the background to understand why. You end up with representations of users that are actually less human.

                                                  This “decontextualization” we see in personas happens in four ways, which we’ll explain below. 

                                                  Personas assume people are static 

                                                  Although many companies still try to box in their employees and customers with outdated personality tests (referring to you, Myers-Briggs), here’s a painfully obvious truth: people are not a fixed set of features. You act, think, and feel differently according to the situations you experience. You appear different to different people; you might act friendly to some, rough to others. And you change your mind all the time about decisions you’ve taken. 

                                                  Modern psychologists agree that while people generally behave according to certain patterns, it’s actually a combination of background and environment that determines how people act and take decisions. The context—the environment, the influence of other people, your mood, the entire history that led up to a situation—determines the kind of person you are in each specific moment. 

                                                  In their attempt to simplify reality, personas do not take this variability into account; they present a user as a fixed set of features. Like personality tests, personas snatch people away from real life. Even worse, people are reduced to a label and categorized as “that kind of person” with no means to exercise their innate flexibility. This practice reinforces stereotypes, lowers diversity, and doesn’t reflect reality. 

                                                  Personas focus on individuals, not the environment

                                                  In the real world, you’re designing for a context, not for an individual. Each person lives in a family, a community, an ecosystem, where there are environmental, political, and social factors you need to consider. A design is never meant for a single user. Rather, you design for one or more particular contexts in which many people might use that product. Personas, however, show the user alone rather than describe how the user relates to the environment. 

                                                  Would you always make the same decision over and over again? Maybe you’re a committed vegan but still decide to buy some meat when your relatives are coming over. As they depend on different situations and variables, your decisions—and behavior, opinions, and statements—are not absolute but highly contextual. The persona that “represents” you wouldn’t take into account this dependency, because it doesn’t specify the premises of your decisions. It doesn’t provide a justification of why you act the way you do. Personas enact the well-known bias called fundamental attribution error: explaining others’ behavior too much by their personality and too little by the situation.

                                                  As mentioned by the Interaction Design Foundation, personas are usually placed in a scenario that’s a “specific context with a problem they want to or have to solve”—does that mean context actually is considered? Unfortunately, what often happens is that you take a fictional character and based on that fiction determine how this character might deal with a certain situation. This is made worse by the fact that you haven’t even fully investigated and understood the current context of the people your persona seeks to represent; so how could you possibly understand how they would act in new situations? 

                                                  Personas are meaningless averages

                                                  As mentioned in Shlomo Goltz’s introductory article on Smashing Magazine, “a persona is depicted as a specific person but is not a real individual; rather, it is synthesized from observations of many people.” A well-known critique to this aspect of personas is that the average person does not exist, as per the famous example of the USA Air Force designing planes based on the average of 140 of their pilots’ physical dimensions and not a single pilot actually fitting within that average seat. 

                                                  The same limitation applies to mental aspects of people. Have you ever heard a famous person say, “They took what I said out of context! They used my words, but I didn’t mean it like that.” The celebrity’s statement was reported literally, but the reporter failed to explain the context around the statement and didn’t describe the non-verbal expressions. As a result, the intended meaning was lost. You do the same when you create personas: you collect somebody’s statement (or goal, or need, or emotion), of which the meaning can only be understood if you provide its own specific context, yet report it as an isolated finding. 

                                                  But personas go a step further, extracting a decontextualized finding and joining it with another decontextualized finding from somebody else. The resulting set of findings often does not make sense: it’s unclear, or even contrasting, because it lacks the underlying reasons on why and how that finding has arisen. It lacks meaning. And the persona doesn’t give you the full background of the person(s) to uncover this meaning: you would need to dive into the raw data for each single persona item to find it. What, then, is the usefulness of the persona?

                                                  The relatability of personas is deceiving

                                                  To a certain extent, designers realize that a persona is a lifeless average. To overcome this, designers invent and add “relatable” details to personas to make them resemble real individuals. Nothing captures the absurdity of this better than a sentence by the Interaction Design Foundation: “Add a few fictional personal details to make the persona a realistic character.” In other words, you add non-realism in an attempt to create more realism. You deliberately obscure the fact that “John Doe” is an abstract representation of research findings; but wouldn’t it be much more responsible to emphasize that John is only an abstraction? If something is artificial, let’s present it as such.

                                                  It’s the finishing touch of a persona’s decontextualization: after having assumed that people’s personalities are fixed, dismissed the importance of their environment, and hidden meaning by joining isolated, non-generalizable findings, designers invent new context to create (their own) meaning. In doing so, as with everything they create, they introduce a host of biases. As phrased by Designit, as designers we can “contextualize [the persona] based on our reality and experience. We create connections that are familiar to us.” This practice reinforces stereotypes, doesn’t reflect real-world diversity, and gets further away from people’s actual reality with every detail added. 

                                                  To do good design research, we should report the reality “as-is” and make it relatable for our audience, so everyone can use their own empathy and develop their own interpretation and emotional response.

                                                  Dynamic Selves: The alternative to personas

                                                  If we shouldn’t use personas, what should we do instead? 

                                                  Designit has proposed using Mindsets instead of personas. Each Mindset is a “spectrum of attitudes and emotional responses that different people have within the same context or life experience.” It challenges designers to not get fixated on a single user’s way of being. Unfortunately, while being a step in the right direction, this proposal doesn’t take into account that people are part of an environment that determines their personality, their behavior, and, yes, their mindset. Therefore, Mindsets are also not absolute but change in regard to the situation. The question remains, what determines a certain Mindset?

                                                  Another alternative comes from Margaret P., author of the article “Kill Your Personas,” who has argued for replacing personas with persona spectrums that consist of a range of user abilities. For example, a visual impairment could be permanent (blindness), temporary (recovery from eye surgery), or situational (screen glare). Persona spectrums are highly useful for more inclusive and context-based design, as they’re based on the understanding that the context is the pattern, not the personality. Their limitation, however, is that they have a very functional take on users that misses the relatability of a real person taken from within a spectrum. 

                                                  In developing an alternative to personas, we aim to transform the standard design process to be context-based. Contexts are generalizable and have patterns that we can identify, just like we tried to do previously with people. So how do we identify these patterns? How do we ensure truly context-based design? 

                                                  Understand real individuals in multiple contexts

                                                  Nothing is more relatable and inspiring than reality. Therefore, we have to understand real individuals in their multi-faceted contexts, and use this understanding to fuel our design. We refer to this approach as Dynamic Selves.

                                                  Let’s take a look at what the approach looks like, based on an example of how one of us applied it in a recent project that researched habits of Italians around energy consumption. We drafted a design research plan aimed at investigating people’s attitudes toward energy consumption and sustainable behavior, with a focus on smart thermostats. 

                                                  1. Choose the right sample

                                                  When we argue against personas, we’re often challenged with quotes such as “Where are you going to find a single person that encapsulates all the information from one of these advanced personas[?]” The answer is simple: you don’t have to. You don’t need to have information about many people for your insights to be deep and meaningful. 

                                                  In qualitative research, validity does not derive from quantity but from accurate sampling. You select the people that best represent the “population” you’re designing for. If this sample is chosen well, and you have understood the sampled people in sufficient depth, you’re able to infer how the rest of the population thinks and behaves. There’s no need to study seven Susans and five Yuriys; one of each will do. 

                                                  Similarly, you don’t need to understand Susan in fifteen different contexts. Once you’ve seen her in a couple of diverse situations, you’ve understood the scheme of Susan’s response to different contexts. Not Susan as an atomic being but Susan in relation to the surrounding environment: how she might act, feel, and think in different situations. 

                                                  Given that each person is representative of a part of the total population you’re researching, it becomes clear why each should be represented as an individual, as each already is an abstraction of a larger group of individuals in similar contexts. You don’t want abstractions of abstractions! These selected people need to be understood and shown in their full expression, remaining in their microcosmos—and if you want to identify patterns you can focus on identifying patterns in contexts.

                                                  Yet the question remains: how do you select a representative sample? First of all, you have to consider what’s the target audience of the product or service you are designing: it might be useful to look at the company’s goals and strategy, the current customer base, and/or a possible future target audience. 

                                                  In our example project, we were designing an application for those who own a smart thermostat. In the future, everyone could have a smart thermostat in their house. Right now, though, only early adopters own one. To build a significant sample, we needed to understand the reason why these early adopters became such. We therefore recruited by asking people why they had a smart thermostat and how they got it. There were those who had chosen to buy it, those who had been influenced by others to buy it, and those who had found it in their house. So we selected representatives of these three situations, from different age groups and geographical locations, with an equal balance of tech savvy and non-tech savvy participants. 

                                                  2. Conduct your research

                                                  After having chosen and recruited your sample, conduct your research using ethnographic methodologies. This will make your qualitative data rich with anecdotes and examples. In our example project, given COVID-19 restrictions, we converted an in-house ethnographic research effort into remote family interviews, conducted from home and accompanied by diary studies.

                                                  To gain an in-depth understanding of attitudes and decision-making trade-offs, the research focus was not limited to the interviewee alone but deliberately included the whole family. Each interviewee would tell a story that would then become much more lively and precise with the corrections or additional details coming from wives, husbands, children, or sometimes even pets. We also focused on the relationships with other meaningful people (such as colleagues or distant family) and all the behaviors that resulted from those relationships. This wide research focus allowed us to shape a vivid mental image of dynamic situations with multiple actors. 

                                                  It’s essential that the scope of the research remains broad enough to be able to include all possible actors. Therefore, it normally works best to define broad research areas with macro questions. Interviews are best set up in a semi-structured way, where follow-up questions will dive into topics mentioned spontaneously by the interviewee. This open-minded “plan to be surprised” will yield the most insightful findings. When we asked one of our participants how his family regulated the house temperature, he replied, “My wife has not installed the thermostat’s app—she uses WhatsApp instead. If she wants to turn on the heater and she is not home, she will text me. I am her thermostat.”

                                                  3. Analysis: Create the Dynamic Selves

                                                  During the research analysis, you start representing each individual with multiple Dynamic Selves, each “Self” representing one of the contexts you have investigated. The core of each Dynamic Self is a quote, which comes supported by a photo and a few relevant demographics that illustrate the wider context. The research findings themselves will show which demographics are relevant to show. In our case, as our research focused on families and their lifestyle to understand their needs for thermal regulation, the important demographics were family type, number and nature of houses owned, economic status, and technological maturity. (We also included the individual’s name and age, but they’re optional—we included them to ease the stakeholders’ transition from personas and be able to connect multiple actions and contexts to the same person).

                                                  To capture exact quotes, interviews need to be video-recorded and notes need to be taken verbatim as much as possible. This is essential to the truthfulness of the several Selves of each participant. In the case of real-life ethnographic research, photos of the context and anonymized actors are essential to build realistic Selves. Ideally, these photos should come directly from field research, but an evocative and representative image will work, too, as long as it’s realistic and depicts meaningful actions that you associate with your participants. For example, one of our interviewees told us about his mountain home where he used to spend every weekend with his family. Therefore, we portrayed him hiking with his little daughter. 

                                                  At the end of the research analysis, we displayed all of the Selves’ “cards” on a single canvas, categorized by activities. Each card displayed a situation, represented by a quote and a unique photo. All participants had multiple cards about themselves.

                                                  4. Identify design opportunities

                                                  Once you have collected all main quotes from the interview transcripts and diaries, and laid them all down as Self cards, you will see patterns emerge. These patterns will highlight the opportunity areas for new product creation, new functionalities, and new services—for new design. 

                                                  In our example project, there was a particularly interesting insight around the concept of humidity. We realized that people don’t know what humidity is and why it is important to monitor it for health: an environment that’s too dry or too wet can cause respiratory problems or worsen existing ones. This highlighted a big opportunity for our client to educate users on this concept and become a health advisor.

                                                  Benefits of Dynamic Selves

                                                  When you use the Dynamic Selves approach in your research, you start to notice unique social relations, peculiar situations real people face and the actions that follow, and that people are surrounded by changing environments. In our thermostat project, we have come to know one of the participants, Davide, as a boyfriend, dog-lover, and tech enthusiast. 

                                                  Davide is an individual we might have once reduced to a persona called “tech enthusiast.” But we can have tech enthusiasts who have families or are single, who are rich or poor. Their motivations and priorities when deciding to purchase a new thermostat can be opposite according to these different frames. 

                                                  Once you have understood Davide in multiple situations, and for each situation have understood in sufficient depth the underlying reasons for his behavior, you’re able to generalize how he would act in another situation. You can use your understanding of him to infer what he would think and do in the contexts (or scenarios) that you design for.

                                                  The Dynamic Selves approach aims to dismiss the conflicted dual purpose of personas—to summarize and empathize at the same time—by separating your research summary from the people you’re seeking to empathize with. This is important because our empathy for people is affected by scale: the bigger the group, the harder it is to feel empathy for others. We feel the strongest empathy for individuals we can personally relate to.  

                                                  If you take a real person as inspiration for your design, you no longer need to create an artificial character. No more inventing details to make the character more “realistic,” no more unnecessary additional bias. It’s simply how this person is in real life. In fact, in our experience, personas quickly become nothing more than a name in our priority guides and prototype screens, as we all know that these characters don’t really exist. 

                                                  Another powerful benefit of the Dynamic Selves approach is that it raises the stakes of your work: if you mess up your design, someone real, a person you and the team know and have met, is going to feel the consequences. It might stop you from taking shortcuts and will remind you to conduct daily checks on your designs.

                                                  And finally, real people in their specific contexts are a better basis for anecdotal storytelling and therefore are more effective in persuasion. Documentation of real research is essential in achieving this result. It adds weight and urgency behind your design arguments: “When I met Alessandra, the conditions of her workplace struck me. Noise, bad ergonomics, lack of light, you name it. If we go for this functionality, I’m afraid we’re going to add complexity to her life.”

                                                  Conclusion

                                                  Designit mentioned in their article on Mindsets that “design thinking tools offer a shortcut to deal with reality’s complexities, but this process of simplification can sometimes flatten out people’s lives into a few general characteristics.” Unfortunately, personas have been culprits in a crime of oversimplification. They are unsuited to represent the complex nature of our users’ decision-making processes and don’t account for the fact that humans are immersed in contexts. 

                                                  Design needs simplification but not generalization. You have to look at the research elements that stand out: the sentences that captured your attention, the images that struck you, the sounds that linger. Portray those, use them to describe the person in their multiple contexts. Both insights and people come with a context; they cannot be cut from that context because it would remove meaning. 

                                                  It’s high time for design to move away from fiction, and embrace reality—in its messy, surprising, and unquantifiable beauty—as our guide and inspiration.

                                                  Performant, sleek and elegant.

                                                  Swift 6 suitable notification observers in iOS

                                                  • iOS
                                                  • Swift

                                                  The author discusses challenges managing side projects, specifically updating SignalPath to Swift 6. They encountered errors related to multiple notification observations but resolved them by shifting to publishers, avoiding sendable closure issues. Although the new approach risks background thread notifications, the compiler is satisfied with the adjustments made to the code.

                                                  I have a couple of side projects going on, although it is always a challenge to find time of them. One of them, SignalPath, is what I created back in 2015. Currently, I have been spending some time to bump the Swift version to 6 which brought a quite a list of errors. In many places I had code what dealt with observing multiple notifications, but of course Swift 6 was not happy about it. This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode characters Show hidden characters let handler: (Notification) -> Void = { [weak self] notification in self?.keyboardInfo = Info(notification: notification) } let names: [Notification.Name] = [ UIResponder.keyboardWillShowNotification, UIResponder.keyboardWillHideNotification, UIResponder.keyboardWillChangeFrameNotification ] observers = names.map({ name -> NSObjectProtocol in return NotificationCenter.default.addObserver(forName: name, object: nil, queue: .main, using: handler) // Converting non-sendable function value to '@Sendable (Notification) -> Void' may introduce data races }) view raw Observer.swift hosted with ❤ by GitHub After moving all of the notification observing to publishers instead, I can ignore the whole sendable closure problem all together. This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode characters Show hidden characters Publishers.Merge3( NotificationCenter.default.publisher(for: UIResponder.keyboardWillShowNotification), NotificationCenter.default.publisher(for: UIResponder.keyboardWillHideNotification), NotificationCenter.default.publisher(for: UIResponder.keyboardWillChangeFrameNotification) ) .map(Info.init) .assignWeakly(to: \.keyboardInfo, on: self) .store(in: &notificationCancellables) view raw Observer.swift hosted with ❤ by GitHub Great, compiler is happy again although this code could cause trouble if any of the notifications are posted from a background thread. But since this is not a case here, I went for skipping .receive(on: DispatchQueue.main). Assign weakly is a custom operator and the implementation looks like this: This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode characters Show hidden characters public extension Publisher where Self.Failure == Never { func assignWeakly<Root>(to keyPath: ReferenceWritableKeyPath<Root, Self.Output>, on object: Root) -> AnyCancellable where Root: AnyObject { return sink { [weak object] value in object?[keyPath: keyPath] = value } } } view raw Combine+Weak.swift hosted with ❤ by GitHub If this was helpful, please let me know on Mastodon@toomasvahter or Twitter @toomasvahter. Feel free to subscribe to RSS feed. Thank you for reading. Support me on Patreon Donate with Paypal Buy me a coffee

                                                  AnyClass protocol and Objective-C methods

                                                  • iOS
                                                  • Swift
                                                  • AnyClass

                                                  AnyClass is a protocol all classes conform to and it comes with a feature I was not aware of. But first, how to I ended up with using AnyClass. While working on code using CoreData, I needed a way to enumerate all the CoreData entities and call a static function on them. If that function […]

                                                  AnyClass is a protocol all classes conform to and it comes with a feature I was not aware of. But first, how to I ended up with using AnyClass. While working on code using CoreData, I needed a way to enumerate all the CoreData entities and call a static function on them. If that function is defined, it runs an entity specific update. Let’s call the function static func resetState(). It is easy to get the list of entity names of the model and then turn them into AnyClass instances using the NSClassFromString() function. This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode characters Show hidden characters let entityClasses = managedObjectModel.entities .compactMap(\.name) .compactMap { NSClassFromString($0) } view raw AnyClass.swift hosted with ❤ by GitHub At this point I had an array of AnyClass instances where some of them implemented the resetState function, some didn’t. While browsing the AnyClass documentation, I saw this: You can use the AnyClass protocol as the concrete type for an instance of any class. When you do, all known @objcclass methods and properties are available as implicitly unwrapped optional methods and properties, respectively. Never heard about it, probably because I have never really needed to interact with AnyClass in such way. Therefore, If I create an @objc static function then I can call it by unwrapping it with ?. Without unwrapping it safely, it would crash because Department type does not implement the function. This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode characters Show hidden characters class Department: NSManagedObject { } class Employee: NSManagedObject { @objc static func resetState() { print("Resetting Employee") } } // This triggers Employee.resetState and prints the message to the console for entityClass in entityClasses { entityClass.resetState?() } view raw AnyClass.swift hosted with ❤ by GitHub It has been awhile since I wrote any Objective-C code, but its features leaking into Swift helped me out here. Reminds me of days filled with respondsToSelector and performSelector. If this was helpful, please let me know on Mastodon@toomasvahter or Twitter @toomasvahter. Feel free to subscribe to RSS feed. Thank you for reading. Support me on Patreon Donate with Paypal Buy me a coffee

                                                  AnyView is everywhere in Xcode 16

                                                  • iOS
                                                  • Xcode
                                                  • Swift

                                                  Xcode 16 introduces a new execution engine for Previews, enhancing project configuration support and improving performance by up to 30%. However, it wraps SwiftUI views in AnyView for debug builds, which can hinder optimization. Users can override this behavior with a custom build setting to maintain performance in debugging.

                                                  Loved to see this entry in Xcode 16’s release notes: Xcode 16 brings a new execution engine for Previews that supports a larger range of projects and configurations. Now with shared build products between Build and Run and Previews, switching between the two is instant. Performance between edits in the source code is also improved for many projects, with increases up to 30%. It has been difficult at times to use SwiftUI previews when they sometimes just stop working with error messages leaving scratch head. Turns out, it comes with a hidden cost of Xcode 16 wrapping views with AnyView in debug builds which takes away performance. If you don’t know it only affects debug builds, one could end up on journey of trying to improve the performance for debug builds and making things worse for release builds. Not sure if this was ever mentioned in any of the WWDC videos, but feels like this kind of change should have been highlighted. As of Xcode 16, every SwiftUI view is wrapped in an AnyView _in debug builds only_. This speeds switching between previews, simulator, and device, but subverts some List optimizations. Add this custom build setting to the project to override the new behavior: `SWIFT_ENABLE_OPAQUE_TYPE_ERASURE=NO` Wrapping in Equatable is likely to make performance worse as it introduces an extra view in the hierarchy for every row. Curt Clifton on Mastodon Fortunately, one can turn off this if this becomes an issue in debug builds. If this was helpful, please let me know on Mastodon@toomasvahter or Twitter @toomasvahter. Feel free to subscribe to RSS feed. Thank you for reading. Support me on Patreon Donate with Paypal Buy me a coffee

                                                  Sorting arrays in Swift: multi-criteria

                                                  • Foundation
                                                  • iOS
                                                  • Swift
                                                  • localizedCaseInsensitiveCompare
                                                  • sort
                                                  • sorted(by:)

                                                  Swift’s foundation library provides a sorted(by:) function for sorting arrays. The areInIncreasingOrder closure needs to return true if the closure’s arguments are increasing, false otherwise. How to use the closure for sorting by multiple criteria? Let’s take a look at an example of sorting an array of Player structs. As said before, the closure should […]

                                                  Swift’s foundation library provides a sorted(by:) function for sorting arrays. The areInIncreasingOrder closure needs to return true if the closure’s arguments are increasing, false otherwise. How to use the closure for sorting by multiple criteria? Let’s take a look at an example of sorting an array of Player structs. Sort by score in descending order Sort by name in ascending order Sort by id in ascending order This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode characters Show hidden characters struct Player { let id: Int let name: String let score: Int } extension Player: CustomDebugStringConvertible { var debugDescription: String { "id=\(id) name=\(name) score=\(score)" } } let players: [Player] = [ Player(id: 0, name: "April", score: 7), Player(id: 1, name: "Nora", score: 8), Player(id: 2, name: "Joe", score: 5), Player(id: 3, name: "Lisa", score: 4), Player(id: 4, name: "Michelle", score: 6), Player(id: 5, name: "Joe", score: 5), Player(id: 6, name: "John", score: 7) ] view raw Sort.swift hosted with ❤ by GitHub As said before, the closure should return true if the left element should be ordered before the right element. If they happen to be equal, we should use the next sorting criteria. For comparing strings, we’ll go for case-insensitive sorting using Foundation’s built-in localizedCaseInsensitiveCompare. This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode characters Show hidden characters let sorted = players.sorted { lhs, rhs in if lhs.score == rhs.score { let nameOrdering = lhs.name.localizedCaseInsensitiveCompare(rhs.name) if nameOrdering == .orderedSame { return lhs.id < rhs.id } else { return nameOrdering == .orderedAscending } } else { return lhs.score > rhs.score } } print(sorted.map(\.debugDescription).joined(separator: "\n")) // id=1 name=Nora score=8 // id=0 name=April score=7 // id=6 name=John score=7 // id=4 name=Michelle score=6 // id=2 name=Joe score=5 // id=5 name=Joe score=5 // id=3 name=Lisa score=4 view raw Sort.swift hosted with ❤ by GitHub If this was helpful, please let me know on Mastodon@toomasvahter or Twitter @toomasvahter. Feel free to subscribe to RSS feed. Thank you for reading. Support me on Patreon Donate with Paypal Buy me a coffee

                                                  How to keep Date’s microseconds precision in Swift

                                                  • Foundation
                                                  • iOS
                                                  • Swift
                                                  • ISO8601DateFormatter

                                                  DateFormatter is used for converting string representation of date and time to a Date type and visa-versa. Something to be aware of is that the conversion loses microseconds precision. This is extremely important if we use these Date values for sorting and therefore ending up with incorrect order. Let’s consider an iOS app which uses […]

                                                  DateFormatter is used for converting string representation of date and time to a Date type and visa-versa. Something to be aware of is that the conversion loses microseconds precision. This is extremely important if we use these Date values for sorting and therefore ending up with incorrect order. Let’s consider an iOS app which uses API for fetching a list of items and each of the item contains a timestamp used for sorting the list. Often, these timestamps have the ISO8601 format like 2024-09-21T10:32:32.113123Z. Foundation framework has a dedicated formatter for parsing these strings: ISO8601DateFormatter. It is simple to use: This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode characters Show hidden characters let formatter = ISO8601DateFormatter() formatter.formatOptions = [.withInternetDateTime, .withFractionalSeconds] let date = formatter.date(from: "2024-09-21T10:32:32.113123Z") print(date?.timeIntervalSince1970) // 1726914752.113 view raw ISO8601.swift hosted with ❤ by GitHub Great, but there is on caveat, it ignores microseconds. Fortunately this can be fixed by manually parsing microseconds and adding the missing precision to the converted Date value. Here is an example, how to do this using an extension. This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode characters Show hidden characters extension ISO8601DateFormatter { func microsecondsDate(from dateString: String) -> Date? { guard let millisecondsDate = date(from: dateString) else { return nil } guard let fractionIndex = dateString.lastIndex(of: ".") else { return millisecondsDate } guard let tzIndex = dateString.lastIndex(of: "Z") else { return millisecondsDate } guard let startIndex = dateString.index(fractionIndex, offsetBy: 4, limitedBy: tzIndex) else { return millisecondsDate } // Pad the missing zeros at the end and cut off nanoseconds let microsecondsString = dateString[startIndex..<tzIndex].padding(toLength: 3, withPad: "0", startingAt: 0) guard let microseconds = TimeInterval(microsecondsString) else { return millisecondsDate } return Date(timeIntervalSince1970: millisecondsDate.timeIntervalSince1970 + microseconds / 1_000_000.0) } } view raw ISO8601.swift hosted with ❤ by GitHub That this code does is first converting the string using the original date(from:) method, followed by manually extracting digits for microseconds by handling cases where there are less than 3 digits or event there are nanoseconds present. Lastly a new Date value is created with the microseconds precision. Here are examples of the output (note that float’s precision comes into play). This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode characters Show hidden characters let dateStrings = [ "2024-09-21T10:32:32.113Z", "2024-09-21T10:32:32.1131Z", "2024-09-21T10:32:32.11312Z", "2024-09-21T10:32:32.113123Z", "2024-09-21T10:32:32.1131234Z", "2024-09-21T10:32:32.11312345Z", "2024-09-21T10:32:32.113123456Z" ] let dates = dateStrings.compactMap(formatter.microsecondsDate(from:)) for (string, date) in zip(dateStrings, dates) { print(string, "->", date.timeIntervalSince1970) } /* 2024-09-21T10:32:32.113Z -> 1726914752.113 2024-09-21T10:32:32.1131Z -> 1726914752.1130998 2024-09-21T10:32:32.11312Z -> 1726914752.1131198 2024-09-21T10:32:32.113123Z -> 1726914752.113123 2024-09-21T10:32:32.1131234Z -> 1726914752.113123 2024-09-21T10:32:32.11312345Z -> 1726914752.113123 2024-09-21T10:32:32.113123456Z -> 1726914752.113123 */ view raw ISO8601.swift hosted with ❤ by GitHub If this was helpful, please let me know on Mastodon@toomasvahter or Twitter @toomasvahter. Feel free to subscribe to RSS feed. Thank you for reading. Support me on Patreon Donate with Paypal Buy me a coffee

                                                  Wrapping async-await with a completion handler in Swift

                                                  • Swift
                                                  • async
                                                  • iOS

                                                  It is not often when we need to wrap an async function with a completion handler. Typically, the reverse is what happens. This need can happen in codebases where the public interface can’t change just right now, but internally it is moving towards async-await functions. Let’s jump in and see how to wrap an async […]

                                                  It is not often when we need to wrap an async function with a completion handler. Typically, the reverse is what happens. This need can happen in codebases where the public interface can’t change just right now, but internally it is moving towards async-await functions. Let’s jump in and see how to wrap an async function, an async throwing function and an async throwing function what returns a value. To illustrate how to use it, we’ll see an example of how a PhotoEffectApplier type has a public interface consisting of completion handler based functions and how it internally uses PhotoProcessor type what only has async functions. The end result looks like this: This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode characters Show hidden characters struct PhotoProcessor { func process(_ photo: Photo) async throws -> Photo { // … return Photo(name: UUID().uuidString) } func setConfiguration(_ configuration: Configuration) async throws { // … } func cancel() async { // … } } public final class PhotoEffectApplier { private let processor = PhotoProcessor() public func apply(effect: PhotoEffect, to photo: Photo, completion: @escaping (Result<Photo, Error>) -> Void) { Task(operation: { try await self.processor.process(photo) }, completion: completion) } public func setConfiguration(_ configuration: Configuration, completion: @escaping (Error?) -> Void) { Task(operation: { try await self.processor.setConfiguration(configuration) }, completion: completion) } public func cancel(completion: @escaping (Error?) -> Void) { Task(operation: { await self.processor.cancel() }, completion: completion) } } view raw PhotoEffectApplier.swift hosted with ❤ by GitHub In this example, we have all the interested function types covered: async, async throwing and async throwing with a return type. Great, but let’s have a look at these Task initializers what make this happen. The core idea is to create a Task, run an operation, and then make a completion handler callback. Since most of the time we need to run the completion on the main thread, then we have a queue argument with the default queue set to the main thread. This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode characters Show hidden characters extension Task { @discardableResult init<T>( priority: TaskPriority? = nil, operation: @escaping () async throws -> T, queue: DispatchQueue = .main, completion: @escaping (Result<T, Failure>) -> Void ) where Success == Void, Failure == any Error { self.init(priority: priority) { do { let value = try await operation() queue.async { completion(.success(value)) } } catch { queue.async { completion(.failure(error)) } } } } } view raw AsyncThrowsValue.swift hosted with ❤ by GitHub This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode characters Show hidden characters extension Task { @discardableResult init( priority: TaskPriority? = nil, operation: @escaping () async throws -> Void, queue: DispatchQueue = .main, completion: @escaping (Error?) -> Void ) where Success == Void, Failure == any Error { self.init(priority: priority) { do { try await operation() queue.async { completion(nil) } } catch { queue.async { completion(error) } } } } } view raw AsyncThrows.swift hosted with ❤ by GitHub This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode characters Show hidden characters extension Task { @discardableResult init( priority: TaskPriority? = nil, operation: @escaping () async -> Void, queue: DispatchQueue = .main, completion: @escaping () -> Void ) where Success == Void, Failure == Never { self.init(priority: priority) { await operation() queue.async { completion() } } } } view raw Async.swift hosted with ❤ by GitHub If this was helpful, please let me know on Mastodon@toomasvahter or Twitter @toomasvahter. Feel free to subscribe to RSS feed. Thank you for reading. Support me on Patreon Donate with Paypal Buy me a coffee

                                                  Dark Augmented Code theme for Xcode

                                                  • Swift
                                                  • Xcode

                                                  After a couple of years, I tend to get tired of looking at the same colour scheme in Xcode. Then I spend quite a bit of time looking for a new theme and then coming back with empty hands. Material default has served me for a while, but it never felt like a perfect colour […]

                                                  After a couple of years, I tend to get tired of looking at the same colour scheme in Xcode. Then I spend quite a bit of time looking for a new theme and then coming back with empty hands. Material default has served me for a while, but it never felt like a perfect colour scheme for me. Therefore, I decided to take on a road of creating a new colour scheme on my own which is going to be named as “Augmented Code (Dark)”. It is available for Xcode and iTerm 2. Download it from here: GitHub If this was helpful, please let me know on Mastodon@toomasvahter or Twitter @toomasvahter. Feel free to subscribe to RSS feed. Thank you for reading. Support me on Patreon Donate with Paypal Buy me a coffee

                                                  Cancellable withObservationTracking in Swift

                                                  • iOS
                                                  • Swift
                                                  • SwiftUI
                                                  • observation
                                                  • withObservationTracking

                                                  Observation framework came out along with iOS 17 in 2023. Using this framework, we can make objects observable very easily. Please refer to @Observable macro in SwiftUI for quick recap if needed. It also has a function withObservationTracking(_:onChange:) what can be used for cases where we would want to manually get a callback when a tracked […]

                                                  Observation framework came out along with iOS 17 in 2023. Using this framework, we can make objects observable very easily. Please refer to @Observable macro in SwiftUI for quick recap if needed. It also has a function withObservationTracking(_:onChange:) what can be used for cases where we would want to manually get a callback when a tracked property is about to change. This function works as a one shot function and the onChange closure is called only once. Note that it is called before the value has actually changed. If we want to get the changed value, we would need to read the value on the next run loop cycle. It would be much more useful if we could use this function in a way where we could have an observation token and as long as it is set, the observation is active. Here is the function with cancellation support. This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode characters Show hidden characters func withObservationTracking( _ apply: @escaping () -> Void, token: @escaping () -> String?, willChange: (@Sendable () -> Void)? = nil, didChange: @escaping @Sendable () -> Void ) { withObservationTracking(apply) { guard token() != nil else { return } willChange?() RunLoop.current.perform { didChange() withObservationTracking( apply, token: token, willChange: willChange, didChange: didChange ) } } } view raw Observation.swift hosted with ❤ by GitHub The apply closure drives which values are being tracked, and this is passed into the existing withObservationTracking(_:onChange:) function. The token closure controls if the change should be handled and if we need to continue tracking. Will and did change are closures called before and after the value has changed. Here is a simple example where we have a view which controls if the observation should be active or not. Changing the value in the view model only triggers the print lines when observation token is set. This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode characters Show hidden characters struct ContentView: View { @State private var viewModel = ViewModel() @State private var observationToken: String? var body: some View { VStack { Text(viewModel.title) Button("Add") { viewModel.add() } Button("Start Observing") { guard observationToken == nil else { return } observationToken = UUID().uuidString observeAndPrint() } Button("Stop Observing") { observationToken = nil } } .padding() } func observeAndPrint() { withObservationTracking({ _ = viewModel.title }, token: { observationToken }, willChange: { [weak viewModel] in guard let viewModel else { return } print("will change \(viewModel.title)") }, didChange: { [weak viewModel] in guard let viewModel else { return } print("did change \(viewModel.title)") }) } } @Observable final class ViewModel { var counter = 0 func add() { counter += 1 } var title: String { "Number of items: \(counter)" } } view raw ContentView.swift hosted with ❤ by GitHub If this was helpful, please let me know on Mastodon@toomasvahter or Twitter @toomasvahter. Feel free to subscribe to RSS feed. Thank you for reading. Support me on Patreon Donate with Paypal Buy me a coffee

                                                  Referencing itself in a struct in Swift

                                                  • Foundation
                                                  • iOS
                                                  • Swift

                                                  It took a long time, I mean years, but it finally happened. I stumbled on a struct which had a property of the same type. At first, it is kind of interesting that the replies property compiles fine, although it is a collection of the same type. I guess it is so because array’s storage […]

                                                  It took a long time, I mean years, but it finally happened. I stumbled on a struct which had a property of the same type. This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode characters Show hidden characters struct Message { let id: Int // This is OK: let replies: [Message] // This is not OK // Value type 'Message' cannot have a stored property that recursively contains it let parent: Message? } view raw Struct.swift hosted with ❤ by GitHub At first, it is kind of interesting that the replies property compiles fine, although it is a collection of the same type. I guess it is so because array’s storage type is a reference type. The simplest workaround is to use a closure for capturing the actual value. This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode characters Show hidden characters struct Message { let id: Int let replies: [Message] private let parentClosure: () -> Message? var parent: Message? { parentClosure() } } view raw Struct2.swift hosted with ❤ by GitHub Or we could go for using a boxed wrapper type. This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode characters Show hidden characters struct Message { let id: Int let replies: [Message] private let parentBoxed: Boxed<Message>? var parent: Message? { parentBoxed?.value} } class Boxed<T> { let value: T init(value: T) { self.value = value } } view raw Struct3.swift hosted with ❤ by GitHub Or if we prefer property wrappers, using that instead. This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode characters Show hidden characters struct Message { let id: Int let replies: [Message] @Boxed var parent: Message? } @propertyWrapper class Boxed<Value> { var value: Value init(wrappedValue: Value) { value = wrappedValue } var wrappedValue: Value { get { value } set { value = newValue } } } view raw Struct4.swift hosted with ❤ by GitHub Then there are also options like changing the struct into class instead, but that is something to consider. Or finally, creating a All in all, it is fascinating how something simple like this actually has a pretty complex background. If this was helpful, please let me know on Mastodon@toomasvahter or Twitter @toomasvahter. Feel free to subscribe to RSS feed. Thank you for reading. Support me on Patreon Donate with Paypal Buy me a coffee

                                                  ScrollView phase changes on iOS 18

                                                  • Swift
                                                  • SwiftUI
                                                  • iOS
                                                  • onScrollPhaseChange
                                                  • ScrollGeometry
                                                  • ScrollPhase
                                                  • ScrollPhaseChangeContext
                                                  • ScrollView

                                                  In addition to scroll related view modifiers covered in the previous blog post, there is another one for detecting scroll view phases aka the state of the scrolling. The new view modifier is called onScrollPhaseChange(_:) and has three arguments in the change closure: old phase, new phase and a context. ScrollPhase is an enum with […]

                                                  In addition to scroll related view modifiers covered in the previous blog post, there is another one for detecting scroll view phases aka the state of the scrolling. The new view modifier is called onScrollPhaseChange(_:) and has three arguments in the change closure: old phase, new phase and a context. ScrollPhase is an enum with the following values: animating – animating the content offset decelerating – user interaction stopped and scroll velocity is decelerating idle – no scrolling interacting – user is interacting tracking – potential user initiated scroll event is going to happen The enum has a convenience property of isScrolling which is true when the phase is not idle. ScrollPhaseChangeContext captures additional information about the scroll state, and it is the third argument of the closure. The type gives access to the current ScrollGeometry and the velocity of the scroll view. Here is an example of a scroll view which has the new view modifier attached. This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode characters Show hidden characters struct ContentView: View { @State private var scrollState: ( phase: ScrollPhase, context: ScrollPhaseChangeContext )? let data = (0..<100).map({ "Item \($0)" }) var body: some View { NavigationStack { ScrollView { ForEach(data, id: \.self) { item in Text(item) .frame(maxWidth: .infinity) .padding() .background { RoundedRectangle(cornerRadius: 8) .fill(Color.cyan) } .padding(.horizontal, 8) } } .onScrollPhaseChange { oldPhase, newPhase, context in scrollState = (newPhase, context) } Divider() VStack { Text(scrollStateDescription) } .font(.footnote.monospaced()) .padding() } } private var scrollStateDescription: String { guard let scrollState else { return "" } let velocity: String = { guard let velocity = scrollState.context.velocity else { return "none" } return "\(velocity)" }() let geometry = scrollState.context.geometry return """ State at the scroll phase change Scrolling=\(scrollState.phase.isScrolling) Phase=\(scrollState.phase) Velocity \(velocity) Content offset \(geometry.contentOffset) Visible rect \(geometry.visibleRect.integral) """ } } view raw ScrollPhase.swift hosted with ❤ by GitHub If this was helpful, please let me know on Mastodon@toomasvahter or Twitter @toomasvahter. Feel free to subscribe to RSS feed. Thank you for reading. Support me on Patreon Donate with Paypal Buy me a coffee

                                                  Recent content on Benoit Pasquier

                                                  From Engineer to Manager: A Year of Growth and Transformation

                                                    It feels like it was yesterday when I became an engineering manager but it has been almost a year. I want to take this time to reflect on the challenges and learnings from this journey.

                                                    Things to know before becoming an Engineering Manager

                                                      The journey from individual contributor to engineering manager isn’t always straightforward. Today, I’ll share what it means to become an engineering manager from my point of view, and a few important points to be aware of before making this transition.

                                                      Transitioning to an Engineering Manager role

                                                        It’s been a while since I haven’t posted anything on my website, it’s because there have been a few changes in 2022 that kept me away from writing. It’s time to resume it.

                                                        Security Application Static Analysis applied to iOS and Gitlab CI

                                                          Security is a big topic in software engineering but how does it apply to mobile development? We care about user experience or mobile performance, security issues are rarely prioritized. This week, I’ll share how to integrate security tools into your CI pipeline to stay aware of your codebase health.

                                                          Being more efficient as a mobile engineer

                                                            I was reading this week about “10x engineer” and what it means in the tech industry. If the title can be questionable, I wanted to reflect on its definition and what it can mean in mobile engineering.

                                                            When to remove your iOS app from the App Store

                                                              For most mobile engineers, the end game is to release our own apps. For the few projects that make it to the App Store, it can be pretty hard to keep them alive over time. Eventually, the question comes up: should I remove my app from the App Store? Today, I’ll share about the thought process that makes me sunset one.

                                                              Weak self, a story about memory management and closure in Swift

                                                                Memory management is a big topic in Swift and iOS development. If there are plenty of tutorials explaining when to use weak self with closure, here is a short story when memory leaks can still happen with it.

                                                                Setting up Auto Layout constraints programmatically in Swift

                                                                  In iOS development, content alignment and spacing is something that can take a lot of our time. Today, let’s explore how to set constraint with UIKit, update them and resolve constraint conflicts.

                                                                  Ten years of blogging, one article at a time

                                                                    Most of people don’t know but I’ve been blogging for some time now. Actually, tomorrow will be ten years. Today is a good time to take a walk on memory lane.

                                                                    Deep linking and URL scheme in iOS

                                                                      Opening an app from an URL is such a powerful iOS feature. Its drives users to your app, and can create shortcuts to specific features. This week, we’ll dive into deep linking on iOS and how to create an URL scheme for your app.

                                                                      Tips and tweaks to integrate Github Action to your iOS project

                                                                        I’ve been exploring more and more tooling around iOS ecosystem. One tool I really enjoy using those days is Github Action as a continuous integration for my projects. Today we’ll dive into tips and tweaks to make the most of it.

                                                                        Flutter and fastlane, how to setup an iOS continuous delivery solution

                                                                          When it comes to iOS development, everybody have their own favorite language and framework: Swift, Objective-C, SwiftUI, React-Native, Flutter and so on. Unlike most of my previous post, today we’re going to leverage some iOS tooling for cross platforms technology: fastlane and Flutter.

                                                                          Currency TextField in SwiftUI

                                                                            Between banking and crypto apps, it’s quite often we interact with currency inputs on daily basis. If creating a localized UITextField can already be tricky in UIKit, I was wondering how hard it would be to do a similar one in SwiftUI. Let’s see today how to create a localized currency TextField in SwiftUI.

                                                                            Open Source checklist for your next Swift library

                                                                              Like many developers, I use open source tools on daily basis. Recently, I’ve got the chance to create one for other teammates and try to think about what I should consider before launching it. Today I share this checklist.

                                                                              Unit testing UIView action and gesture in Swift

                                                                                A big part of the developer journey is make sure our code behaves as expected. It’s best practice to setup tests that allow us to test quickly and often that nothing is broken. If unit testing is common practice to check the business logic, we can also extend it to cover some specific UI behaviors. Let’s how to unit test views and gesture in UIKit.

                                                                                Dependency injection and Generics to create a modular app in Swift

                                                                                  When we talk about modular app, we rarely mention how complex it can be over time and get out of hand. In most cases, importing frameworks into one another is a reasonable solution but we can do more. Let’s explore how with dependency inversion in Swift and how to create order into our components.

                                                                                  Things I wish I knew in my early coding career

                                                                                    For the past few years, I had the opportunity to mentor new joiners through different roles. In some aspects, I could see myself in them the same way I started years back: eager to prove themselves, jumping on the code and hacking around.

                                                                                    I tried to think about what I learnt the hard way since my first role in the tech industry and how could I help them learn the easy way.

                                                                                    Create a web browser with WebKit and SwiftUI

                                                                                      Recently, I’ve been more and more curious about web experience through mobile apps. Most of web browser apps look alike, I was wondering how could I recreate one with WebKit and SwiftUI. Let’s dive in.

                                                                                      Migrating an iOS app to SwiftUI - Database with Realm

                                                                                        To move an existing iOS app codebase to SwiftUI can quickly become a challenge if we don’t scope the difficulties ahead. After covering the navigation and design layer last week, it’s time to dive deeper into the logic and handle the code migration for a database and the user preferences.

                                                                                        Migrating an iOS app to SwiftUI - Navigation & Storyboards

                                                                                          If SwiftUI is great for many things, migrating completely an existing app codebase to it can be really tricky. In a series of blog posts, I’ll share how to migrate an iOS app written in Swift with UIKit to SwiftUI. Today, let’s start with the navigation and the UI components with storyboards.

                                                                                          Creating a webcam utility app for macOS in SwiftUI

                                                                                            Did you ever have to share your screen and camera together? I recently did and it was that easy. How hard could it be to create our own? Today, we’ll code our own webcam utility app for macOS in SwiftUI.

                                                                                            Migrating MVVM architecture from RxSwift to Combine

                                                                                              It’s been almost two years that Combine has been introduced to the Apple developer community. As many developer, you want to migrate your codebase to it. You don’t want to be left behind but you’re not sure where to start, maybe not sure if you want to jump to SwiftUI either. Nothing to worry, let’s see step by step how to migrate an iOS sample app using UIKit and RxSwift to Combine.

                                                                                              How to display date and time in SwiftUI

                                                                                                Displaying dates or times is a very common requirement for many apps, often using a specific date formatter. Let’s see what SwiftUI brings to the table to make it easier for developers.

                                                                                                Create a dynamic onboarding UI in Swift

                                                                                                  When creating new features, it’s really important to think about how our users will use it. Most of the time, the UI is straightforward enough. However, sometimes, you will want to give some guidance, to highlight a button or a switch, with a message attached. Today, we’ll create a reusable and adaptable overlay in Swift to help onboard mobile users for any of your features.

                                                                                                  Goodbye 2020 - A year in perspective

                                                                                                    Close to the end of the year, I tend to list what I’ve accomplished but also what didn’t go so well, to help me see what can I do better next year. With couple days early, it’s time to look back at 2020.

                                                                                                    How to pass data between views using Coordinator pattern in Swift

                                                                                                      A question that comes back often when using Coordinator pattern in iOS development is how to pass data between views. Today I’ll share different approaches for a same solution, regardless if you are using MVVM, MVC or other architectural design pattern.

                                                                                                      Automating App Store localized screenshots with XCTest and Xcode Test Plan

                                                                                                        One reason I like so much working on native mobile apps is to deliver the user experience based on their region and location. Although, for every update, it can be painful for developers to recapture screenshots foreach available language. Today, I’ll share how to automate this with UI tests and Xcode tools.

                                                                                                        Playing Video with AVPlayer in SwiftUI

                                                                                                          I’ve been experiencing more and more with SwiftUI and I really wanted to see what we can do with video content. Today I’ll share my findings, showing how to play video using AVFoundation in SwiftUI, including some mistakes to avoid.

                                                                                                          With Catalyst and SwiftUI multi-platform, should you create a macOS version of your app?

                                                                                                            With Mac Catalyst and SwiftUI support for macOS, Apple has been pushing new tools to the community for the past couple years to create new services on Mac computers. Does it mean you should do too? Here are couple things to consider first.

                                                                                                            Create a watchOS app in SwiftUI

                                                                                                              Designing a watchOS app in Swift always felt to be quite tricky. I could spend hours tweaking redoing layout and constraints. With SwiftUI supporting watchOS, I wanted to have a new try at it, releasing a standalone app for Apple Watch.

                                                                                                              As software engineer, how to face the impostor syndrome?

                                                                                                                Shortly stepping back from coding for a week and reading about the community, I realized it how easy it is to be crushed by anxiety: I see so many great things happening every day, things I want to be part of, but at the same time getting anxiety to be good enough. This is my thoughts of how to face the impostor syndrome.

                                                                                                                Advanced testing tips in Xcode

                                                                                                                  In the last couple years, Apple has made some good efforts to improve their testing tools. Today, I’ll walk you through some tips to make sure your test suite run at their best capacity.

                                                                                                                  Atomic properties and Thread-safe data structure in Swift

                                                                                                                    A recurring challenge in programming is accessing a shared resource concurrently. How to make sure the code doesn’t behave differently when multiple thread or operations tries to access the same property. In short, how to protect from a race condition?

                                                                                                                    Deploying your Swift code on AWS Lambda

                                                                                                                      About a month ago, it became possible to run Swift code on AWS Lambda. I was really interesting to try and see how easy it would be to deploy small Swift functions as serverless application. Let’s see how.

                                                                                                                      Introduction to MVVM pattern in Objective-C

                                                                                                                        Even though the iOS ecosystem is growing further every day from Objective-C, some companies still heavily rely on it. A week away for another wave of innovation from WWDC 2020, I thought it would be interesting to dive back into Objective-C starting with a MVVM pattern implementation.

                                                                                                                        100 day challenge of data structure and algorithm in Swift

                                                                                                                          Since January, I’ve been slowing down blogging for couple reasons: I started doubting about myself and the quality of my content but I also wanted to focus more on some fundamentals I felt I was missing. So I committed to a “100 day challenge” coding challenge, focused on data structure and algorithm in Swift.

                                                                                                                          Data Structure - Implementing a Tree in Swift

                                                                                                                            Following up previous articles about common data structure in Swift, this week it’s time to cover the Tree, a very important concept that we use everyday in iOS development. Let’s dive in.

                                                                                                                            Using Key-Value Observing in Swift to debug your app

                                                                                                                              Recently, I was looking into a bug where the UITabBar was inconsistently disappearing on specific pages. I tried different approaches but I couldn’t get where it got displayed and hidden. That’s where I thought about KVO.

                                                                                                                              Data Structure - Coding a Stack in Swift

                                                                                                                                After covering last week how to code a Queue in Swift, it sounds natural to move on to the Stack, another really handy data structure which also find his place in iOS development. Let’s see why.

                                                                                                                                Data Structure - How to implement a Queue in Swift

                                                                                                                                  Recently revisiting computer science fundamentals, I was interested to see how specific data structure applies to iOS development, starting this week one of most common data structure: the queue.

                                                                                                                                  Should I quit blogging?

                                                                                                                                    When I started this blog in 2012, it was at first to share solution to technical problem I encountered on my daily work, to give back to the community. Over the years, I extended the content to other projects and ideas I had. Nowadays, I get more and more feedbacks on it, sometimes good, sometimes bad, either way something always good to learn from.

                                                                                                                                    Start your A/B testing journey with SwiftUI

                                                                                                                                      Last year, I shared a solution to tackle A/B testing on iOS in swift. Now that we have SwiftUI, I want to see if there is a better way to implement A/B testing. Starting from the same idea, I’ll share different implementations to find the best one.

                                                                                                                                      How to make your iOS app smarter with sentiment analysis

                                                                                                                                        For quite some time now, I’ve been developing an interest to data analysis to find new ways to improve mobile app. I’ve recently found some time to experiment neural language processing for a very specific usecase related to my daily work, sentiment analysis of customer reviews on fashion items.

                                                                                                                                        Localization with SwiftUI, how to preview your localized content

                                                                                                                                          With SwiftUI being recently introduced, I was curious if we could take advantage of SwiftUI preview to speed up testing localization and make sure your app looks great for any language.

                                                                                                                                          SwiftUI - What has changed in your MVVM pattern implementation

                                                                                                                                            Introduced in 2019, Apple made UI implementation much simpler with With SwiftUI its UI declarative framework. After some time experiencing with it, I’m wondering today if MVVM is still the best pattern to use with. Let’s see what has changed, implementing MVVM with SwiftUI.

                                                                                                                                            Data Structure and Algorithm applied to iOS

                                                                                                                                              When asked about data structure and algorithm for an iOS development role, there is always this idea that it’s not a knowledge needed. Swift got already native data structure, right? Isn’t the rest only UI components? That’s definitely not true. Let’s step back and discuss about data structure and algorithm applied to iOS development.

                                                                                                                                              How to integrate Redux in your MVVM architecture

                                                                                                                                                For last couple years, I’ve been experimenting different architectures to understand pros and cons of each one of them. Redux architecture is definitely one that peek my curiosity. In this new post, I’ll share my finding pairing Redux with MVVM, another pattern I’m familiar with and more importantly why you probably shouldn’t pair them.

                                                                                                                                                Software engineer, it's okay to not have a side project

                                                                                                                                                  There is a believe that any software developer must contribute or have a side project to work on. Even if it’s great to have, I think there is something bigger at stake doing that.

                                                                                                                                                  How to build a modular architecture in iOS

                                                                                                                                                    Over time, any code base grows along with the project evolves and matures. It creates two main constraints for developers: how to have a code well organized while keeping a build time as low as possible. Let’s see how a modular architecture can fix that.

                                                                                                                                                    Analytics - How to avoid common mistakes in iOS

                                                                                                                                                      I have been interested in analytics tools for a while, especially when it’s applied to mobile development. Over the time, I saw many code mistakes when implementing an analytical solution. Some of them can be easily avoided when developer got the right insights, let’s see how.

                                                                                                                                                      Apps and Projects

                                                                                                                                                        Over the time, I spent quite some time building different apps and projects. Here is the list of the one that became something. Lighthouse is a webapp written in Swift to test universal link configuration. Driiing, a running companion app to signal runners coming to pedestrians. Appy, an iOS app that takes helps you quit your bad habit. Square is an resizing tool for app icons written in Rust. Japan Direct, an itinerary app for iOS to visit Japan like a local.

                                                                                                                                                        Events and Talks

                                                                                                                                                          I recently tried to be more active in the iOS community. Becoming speaker and talks to events is my next challenged. Here is the list of talks I’ve made so far. My very first one was recently at iOS meetup Singapore in July 2019, talking about scalability of an iOS app along with your team. You can read more about this whole new journey here. I also got chance to be part of iOS Conf SG 2021, an online version of the very popular international event iOS Conf SG.

                                                                                                                                                          Code Coverage in Xcode - How to avoid a vanity metric for your iOS app

                                                                                                                                                            Since Xcode 7, iOS developers can generate a code coverage for their app: a report showing which area of their app is covered by unit tests. However, this is isn’t always accurate, let’s see why you should not base your code health only on code coverage.

                                                                                                                                                            Appy, an iOS app to help you quit your bad habits

                                                                                                                                                              It has been a while since I wanted to create something helpful to others, not than just another random app. Then I found out there were not so many great sobriety apps, so I launched one. Here is Appy, to help you quit your bad habits.

                                                                                                                                                              How to integrate Sign In with Apple in your iOS app

                                                                                                                                                                With iOS13, Apple is introducing “Sign In with Apple”, an authentication system that allows user create an account for your app based on their Apple ID. Let’s see how to integrate it in your app and be ready for iOS13 launch.

                                                                                                                                                                How to avoid common mistakes for your first iOS talk

                                                                                                                                                                  I have been a bit more quite for the past couple weeks to take a break of my weekly routine of blogging. It’s not because I was lazy, but I wanted to take time to digest WWDC. At the same time I had other running projects, one was my first talk at an iOS meetup. Here is couple tips I would have love to hear earlier.

                                                                                                                                                                  First steps in functional reactive programming in Swift with Apple Combine framework

                                                                                                                                                                    One debate over the past year in the iOS ecosystem was the around functional reactive framework like RxSwift or ReactiveCocoa. This year at WWDC2019, Apple took position on it and released their own functional reactive programming framework, here is Combine.

                                                                                                                                                                    iOS Code Review - Health check of your Swift code

                                                                                                                                                                      I have been recently asked to review an iOS application to see how healthy was the code base, if it follows the best practices and how easy it would be to add new features to it. If I review some code on daily basis for small pull requests, analyzing one whole app at once is quite different exercise. Here is some guidelines to help doing that analysis.

                                                                                                                                                                      How to implement Coordinator pattern with RxSwift

                                                                                                                                                                        After weeks experimenting different patterns and code structures, I wanted to go further in functional reactive programming and see how to take advantage of it while following Coordinator pattern. This post describes how integrate RxSwift with Coordinator pattern and which mistakes to avoid.

                                                                                                                                                                        ReSwift - Introduction to Redux architecture in Swift

                                                                                                                                                                          If you are not familiar with it, Redux a Javascript open source library designed to manage web application states. It helps a lot to make sure your app always behaves as expected and makes your code easier to test. ReSwift is the same concept but in Swift. Let’s see how.

                                                                                                                                                                          Tools and tips to scale your iOS project along with your team

                                                                                                                                                                            We often talk about scalability of iOS app but not much about the project itself or the team. How to prepare your project to move from 2 developers to 6? How about 10 or 20 more? In that research, I’ve listed different tools to prepare your team and project to scale.

                                                                                                                                                                            RxSwift & MVVM - Advanced concepts of UITableView with RxDataSources

                                                                                                                                                                              For the past months, I keep going further in RxSwift usage. I really like the idea of forwarding events through different layers but the user interface stays sometimes a challenge. Today, I’ll describe how to use RxDataSources to keep things as easy as possible.

                                                                                                                                                                              How to use Vapor Server to write stronger UI tests in Swift

                                                                                                                                                                                Even if I usually stay focus on the customer facing side of mobile development, I like the idea of writing backend api with all the security that Swift includes. Starting small, why not using Swift Server for our UI Tests to mock content and be at the closest of the real app.

                                                                                                                                                                                How to bootstrap your iOS app to iterate faster

                                                                                                                                                                                  I love developing new iOS apps and create new products. However, regardless of the project, it often need a team to mix the required skills: design, coding, marketing. Although, this less and less true, so let’s see how to bootstrap your iOS app.

                                                                                                                                                                                  RxSwift & MVVM - How to use RxTests to test your ViewModel

                                                                                                                                                                                    Not that long ago, I wrote how to pair RxSwift with MVVM architecture in an iOS project. Even if I refactored my code to be reactive, I omitted to mention the unit tests. Today I’ll show step by step how to use RxTest to unit test your code.

                                                                                                                                                                                    Down the rabbit hole of iOS design patterns

                                                                                                                                                                                      For years now, the whole iOS community has written content about the best way to improve or replace the Apple MVC we all started with, myself included. MVC, MVVM, MVP, VIPER? Regardless the type of snake you have chosen, it’s time to reflect on that journey.

                                                                                                                                                                                      Coordinator & MVVM - Clean Navigation and Back Button in Swift

                                                                                                                                                                                        After introducing how to implement Coordinator pattern with an MVVM structure, it feels natural for me to go further and cover some of the blank spots of Coordinator and how to fix along the way.

                                                                                                                                                                                        Reversi - An elegant A/B testing framework for iOS in Swift.

                                                                                                                                                                                          Couple weeks ago, I heard somebody talking about A/B testing in iOS and how “mobile native A/B testing is hard to implement”. It didn’t sound right to me. So I build a tiny framework for that in Swift. Here is Reversi.

                                                                                                                                                                                          Dos and Don’ts for creating an onboarding journey on iOS

                                                                                                                                                                                            I was recently searching for onboarding journey in iOS, that succession of screens displayed at the first launch of a freshly installed mobile app. But regardless how beautiful the design can be, why so many people are tempted to skip it. I listed things to consider while creating an onboarding journey for your iOS app.

                                                                                                                                                                                            Introduction to Coordinator pattern in Swift

                                                                                                                                                                                              After some times creating different iOS apps following an MVVM pattern, I’m often not sure how to implement the navigation. If the View handles the rendering and user’s interactions and the ViewModel the service or business logic, where does the navigation sit? That’s where Coordinator pattern takes place.

                                                                                                                                                                                              How to create a customer focused mobile app

                                                                                                                                                                                                Last year, I launched with a friend Japan Direct, an itinerary app for Japan travellers. Even if the first version came up quite quickly, I kept iterate but always staying focus on customer feedback first. Almost a year later, it’s good time for synthesis, see what worked and how we created a customer focused app.

                                                                                                                                                                                                Adaptive Layout and UICollectionView in Swift

                                                                                                                                                                                                  Apple introduced in iOS8 trait variations that let developers create more adaptive design for their mobile apps, reducing code complexity and avoiding duplicated code between devices. But how to take advantage of variations for UICollectionView?

                                                                                                                                                                                                  This post will cover how to setup variations via Interface Builder as well but also programatically, using AutoLayout and UITraitVariation with a UICollectionView to create a unique adaptive design.

                                                                                                                                                                                                  RxSwift & MVVM - An alternative structure for your ViewModel

                                                                                                                                                                                                    For last couple weeks, I’ve worked a lot about how to integrate RxSwift into an iOS project but I wasn’t fully satisfied with the view model. After reading many documentation and trying on my side, I’ve finally found a structure I’m happy with.

                                                                                                                                                                                                    Create a machine learning model to classify Fashion images in Swift

                                                                                                                                                                                                      Since WWDC18, Apple made it way easier to developers to create model for machine learning to integrate iOS apps. I have tried myself in the past different models, one for face detection and create another with Tensorflow to fashion classification during a hackathon. Today I’ll share with you how I create a model dedicated to fashion brands.

                                                                                                                                                                                                      How to integrate RxSwift in your MVVM architecture

                                                                                                                                                                                                        It took me quite some time to get into Reactive Programming and its variant adapted for iOS development with RxSwift and RxCocoa. However, being fan of MVVM architecture and using an observer design pattern with it, it was natural for me to revisit my approach and use RxSwift instead. Thats what I’m going to cover in this post.

                                                                                                                                                                                                        Design pattern in Swift - Delegation

                                                                                                                                                                                                          The delegation pattern is one of the most common design pattern in iOS. You probably use it on daily basis without noticing, every time you create a UITableView or UICollectionView and implementing their delegates. Let’s see how it works and how to implement it in Swift.

                                                                                                                                                                                                          UI testing - How to inspect your iOS app with Calabash and Appium

                                                                                                                                                                                                            Part of the journey in software development is testability. Regarding mobile development, testability for your iOS app goes through UI testing. Let’s see different way to inspect any UI elements and prepare your iOS app for UI automation testing.

                                                                                                                                                                                                            Don't forget what you've accomplished this year

                                                                                                                                                                                                              While wishing a happy new year around me, people helped me realised how many good things happened to me this year. Funny enough, while listing my goals for 2019, I found the matching list for 2018 and here is what really happened.

                                                                                                                                                                                                              Develop your creativity with ephemeral iOS apps

                                                                                                                                                                                                                From my first year studying computer science, I’ve always wanted to do more on my free time and create simple projects that could be useful for others. I won’t lie, I wish I was able to monetize them but regardless the outcome, learning was always part of the journey.

                                                                                                                                                                                                                Design pattern in Swift - Observers

                                                                                                                                                                                                                  During this year, I have blogged quite a bit about code architecture in Swift and I’ve realized that I didn’t explain much about which design pattern to use with it. In a series of coming posts, I will cover different design patterns, starting now with observer.

                                                                                                                                                                                                                  Build a visual search app with TensorFlow in less than 24 hours

                                                                                                                                                                                                                    For a while now, I really wanted to work on a machine learning project, especially since Apple let you import trained model in your iOS app now. Last September, I took part of a 24h hackathon for an e-commerce business, that was my chance to test it. The idea was simple: a visual search app, listing similar products based on a picture.

                                                                                                                                                                                                                    Always keep your skills sharp

                                                                                                                                                                                                                      It has been couple months since my last post and despite the idea, a lot of things kept me busy far from blogging. Looking back, it all articulates around the same idea: why it’s important to always keep your skills sharp.

                                                                                                                                                                                                                      How to detect if your iOS app hits product market fit

                                                                                                                                                                                                                        Couple months ago, I’ve built an app and released it on the App Store. Since published, I really wanted to see how it lives and understand how to make it grow. Ideally, I wanted to know if there is a product / market fit. In the article, I describe each steps and ideas that helped my app grow and what I learnt from it.

                                                                                                                                                                                                                        The best way to encode and decode JSON in Swift4

                                                                                                                                                                                                                          Most of mobile apps interact at some point with remote services, fetching data from an api, submitting a form… Let’s see how to use Codable in Swift to easily encode objects and decode JSON in couple lines of codes.

                                                                                                                                                                                                                          Why choosing XCUITest framework over Appium for UI automation testing

                                                                                                                                                                                                                            I recently went for a Swift conference and UI automation testing was one of the subject. I already mentioned it with Appium in the past but I think it’s time to go back to it and explain why today I still prefer using Apple’s testing framework instead.

                                                                                                                                                                                                                            Why and how to add home screen shortcut for your iOS app

                                                                                                                                                                                                                              I recently implemented 3D touch for an app and I was very interested about home screen quick actions. If it can be a good way to improve user experience, it doesn’t mean your app always needs it. In this article, I explain how to add home screen shortcut for your app in Swift but mostly why can justify implementing it.

                                                                                                                                                                                                                              What I learn from six years of blogging

                                                                                                                                                                                                                                I recently realised that my first blog post was 6 years ago. It’s a good occasion for me to do a little retrospective and share what I learnt from blogging over the years.

                                                                                                                                                                                                                                Error handling in MVVM architecture in Swift

                                                                                                                                                                                                                                  If you care about user experience, error handling is a big part you have to cover. We can design how an mobile app looks like when it works, but what happen when something goes wrong. Should we display an alert to the user? Can the error stay silent? And mostly how to implement it the best way with your current design pattern? Let’s see our options while following MVVM pattern.

                                                                                                                                                                                                                                  From the idea of an iOS app to App Store in 10 hours

                                                                                                                                                                                                                                    The best way to learn and become more creative as a developer is to focus on a side project. A really good friend coming back from Japan came to me with an idea when I needed that side project. This is how we created Japan Direct, from the idea to the App Store in almost no time.

                                                                                                                                                                                                                                    How to optimise your UICollectionView implementation in Swift

                                                                                                                                                                                                                                      For the last couple weeks, I tried to step back on my development to analyse what is time consuming in mobile development. I realised that most of new views are based on same approach, reimplementing an similar structure around a UICollectionView or UITableView.

                                                                                                                                                                                                                                      What if I can have a more generic approach where I can focus only on what matters, the user experience. That’s what I tried to explore in this article.

                                                                                                                                                                                                                                      Support universal links in your iOS app

                                                                                                                                                                                                                                        Last couple weeks, I have traveled with only my iPhone with me and I realised how many apps I daily used still relying on their websites. Even with the right iOS app installed, I had to browse on Safari app to get specific details. That is why it’s so important to support universal links in iOS. Let me show you how.

                                                                                                                                                                                                                                        Make the most of enumerations in Swift

                                                                                                                                                                                                                                          Enumerations have changed a lot between Objective-C and Swift. We can easily forget how useful and powerful it can. I wanted to get back to it through simple examples to make the most of it.

                                                                                                                                                                                                                                          How to integrate Firebase in your iOS app

                                                                                                                                                                                                                                            Firebase is a set of tools introduced by Google to build better mobile apps. I worked with this many times and even if it’s straight forward to integrate, here are couple advices of implementation to make the most of it.

                                                                                                                                                                                                                                            From lean programming to growth marketing

                                                                                                                                                                                                                                              I recently followed a growth marketing course, introducing mindset and methodology to make a company grow. I learnt a lot from it and since, I try to apply this knowledge on a daily basis. After more reflection on it, a lot of ideas looked very similar to software development job, this is the part I would like to share.

                                                                                                                                                                                                                                              Introduction to Protocol-Oriented Programming in Swift

                                                                                                                                                                                                                                                When I started coding years ago, it was all about object oriented programming. With Swift, a new approach came up, making the code even easier to reuse and to test, Protocol-Oriented Programming.

                                                                                                                                                                                                                                                Why you should abstract any iOS third party libraries

                                                                                                                                                                                                                                                  If you have an iOS app, you might have integrated external libraries and tools to help you getting your product ready faster. However your iOS architecture and swift code shouldn’t depend on those libraries.

                                                                                                                                                                                                                                                  Optimise Xcode build to speed Fastlane

                                                                                                                                                                                                                                                    The best part of continuous integration is the ability to automatically run tests and build apps, ready to be deployed. However, automatic build doesn’t mean smart or optimised build. Here are some tips I collected along the way to speed up delivery process.

                                                                                                                                                                                                                                                    Unit Testing your MVVM architecture in Swift

                                                                                                                                                                                                                                                      To be sure new code won’t break old one already implemented, it’s best practice to write unit tests. When it comes to app architectures, it can be a challenge to write those tests. Following an MVVM pattern, how to unit test a view and its viewModel? That’s what I would like to cover here using dependency injection.

                                                                                                                                                                                                                                                      How to implement MVVM pattern in Swift from scratch

                                                                                                                                                                                                                                                        Creating a new app often raise the question of what architecture to choose, which pattern would fit best. In this post, I show how to implement an MVVM pattern around a sample app in Swift.

                                                                                                                                                                                                                                                        Kronos, an iOS app to make runners love numbers

                                                                                                                                                                                                                                                          In 2017, I managed to run about 750 miles (1200 km), it’s 250 miles more than the year before. I know it because Strava tracked it for me. I’m such a fan of their product than using it becomes part of my routine and my training. Although, during that journey, I always missed numbers that talked to me. That is how I created Kronos.

                                                                                                                                                                                                                                                          Starting your year the right way

                                                                                                                                                                                                                                                            Starting a new year is always exciting. Most of us have new resolutions and a bucket list we want to accomplish for 2018 but it’s quite often that as soon something go wrong, the whole list goes wrong. Here is some advices to keep track on it.

                                                                                                                                                                                                                                                            Do you need a Today extension for your iOS app?

                                                                                                                                                                                                                                                              For the last couple months, I observed Today extensions of some of iOS apps I daily use to see when those widgets are useful and how to justify developing one. Here are my conclusions.

                                                                                                                                                                                                                                                              Face detection in iOS with Core ML and Vision in Swift

                                                                                                                                                                                                                                                                With iOS11, Apple introduced the ability to integrate machine learning into mobile apps with Core ML. As promising as it sounds, it also has some limitations, let’s discover it around a face detection sample app.

                                                                                                                                                                                                                                                                Making five years in three

                                                                                                                                                                                                                                                                  I always thought a good way to stay motivated and look forward is to have goal you can accomplish in a short term, about 3 to 12 months maximum. It’s at least the way I dealt with my life after being graduated.

                                                                                                                                                                                                                                                                  How to use Javascript with WKWebView in Swift

                                                                                                                                                                                                                                                                    Embedding web into native apps is a frequent approach to quickly add content into a mobile app. It can be for a contact form but also for more complex content to bootstrap a missing native feature. But you can go further and build a two bridge between Web and Mobile using JavaScript and Swift.

                                                                                                                                                                                                                                                                    Using Charles as SSL Proxy on iOS

                                                                                                                                                                                                                                                                      Most of apps use HTTPS request to access data, and because of SSL encryption, it can be tough to debug it from iOS apps that are already on the App Store. Charles is the perfect tool to help you inspect your HTTPS requests.

                                                                                                                                                                                                                                                                      Create your private CocoaPod library

                                                                                                                                                                                                                                                                        Libraries and external dependencies have always been a good way to avoid developers recreate something already existing. It’s also a good way to help each other and leaving something reusable. CocoaPods is the most used tool to manage dependencies around Xcode projects. Let’s see how to create your own private pod.

                                                                                                                                                                                                                                                                        How to be what you want to be

                                                                                                                                                                                                                                                                          Starting 2017, I decided that this year would be mine. It doesn’t mean everything would be given, but I would stay open to new opportunities and stay actor of my life, be what I want to be. Half way, here is time for reflection.

                                                                                                                                                                                                                                                                          Build your Android app with Bitbucket Pipeline and HockeyApp

                                                                                                                                                                                                                                                                            Configuring a continuous integration can be tricky for mobile apps. Let’s see how quick it is to build an Android app with Bitbucket Pipeline and deliver it with App Center app (ex HockeyApp).

                                                                                                                                                                                                                                                                            How to migrate from WordPress to a static website with Hugo and AWS

                                                                                                                                                                                                                                                                              Recently, I got a reminder that my domain name and shared host would eventually expire this summer. I always had a WordPress for my website and thought it was time to move on for something easier to maintain. Here is how I managed to migrate my WordPress blog to a static website with Hugo on AWS.

                                                                                                                                                                                                                                                                              10 weeks training with running mobile apps

                                                                                                                                                                                                                                                                                This year, I finally signed up for a marathon and the way I use running apps and their services have clearly changed. Giving the best user experience around those services is essential to make the app useful. Here is my feedback as a mobile developer during my last 10 weeks training.

                                                                                                                                                                                                                                                                                French Election 2017, don't get fooled by surveys

                                                                                                                                                                                                                                                                                  Technology has never been as important as today in politics. Everything is related to numeric data. If we only analyze news around US elections in 2016, it was mostly about email hacks, fake news in daily news feed, or online surveys. Concerned about French elections 2017, I wanted to be a bit more active and do something related the last one: to online surveys.

                                                                                                                                                                                                                                                                                  Six months of Android development

                                                                                                                                                                                                                                                                                    In my current role at Qudini, I started as an iOS developer. My main task was to create and improve our mobile products for iOS devices based on what was already done on Android. However I wanted to be more efficient in my job and I thought it could be by impacting more users through Android development. Once our iOS apps were at the same level as the Android one, I push the idea that it would be better I start doing Android too. Here is my feedback after 6 months developing on Android.

                                                                                                                                                                                                                                                                                    Feature flag your mobile app with Apptimize

                                                                                                                                                                                                                                                                                      Recently, I got the chance to integrate feature flags into a mobile app I work on. The idea of feature flag is simple, it lets you enable and manage features in your mobile app remotely without requiring a new release. Let see the benefice of it and how integrate a feature flag solution like Apptimize’s one.

                                                                                                                                                                                                                                                                                      Xcode script automation for SauceLabs

                                                                                                                                                                                                                                                                                        Couple months ago, I’ve tried to set a mobile testing environment with Appium and one of the best tools to execute these tests was SauceLabs, a cloud platform dedicated for testing. SauceLabs is pretty easy to use but here is couple tricks to make even easier.

                                                                                                                                                                                                                                                                                        Mobile continuous delivery with bitrise

                                                                                                                                                                                                                                                                                          Continuous integration and continuous delivery is something I wanted to do a while ago, specially since Apple accelerated its approval process to publish new apps on its mobile store. It can now takes less than a day to have an update available for your mobile users: continuous integration and continuous delivery makes more sense than ever on mobile apps.

                                                                                                                                                                                                                                                                                          How can a developer do marketing?

                                                                                                                                                                                                                                                                                            Working as a mobile developer, I created multiple apps during last couple years for companies I worked for, and eventually for personal projects. At the beginning, I though the goal for any developer was the release itself: shipping code and moving on, but I quickly found out that it was more frustrating than everything to stop here. That’s how I started thinking about what should be the next step and if a developer can actually do marketing and how.

                                                                                                                                                                                                                                                                                            Growth Hacking applied to your LinkedIn profile to get a new job

                                                                                                                                                                                                                                                                                              I recently finished Growth Hacking Marketing by Ryan Holiday and learn a lot of things about it. Some of them remembered me the way I found my job in London and how I tweaked my LinkedIn profile to fit the targeted audience.

                                                                                                                                                                                                                                                                                              How to create an iOS app for Sens'it tracker in Swift

                                                                                                                                                                                                                                                                                                Sens’it is small tracker developed by Sigfox and given for free during events to let people test the Sigfox low frequency IoT network. Let’s see how to create an iOS app in Swift based on Sens’it api.

                                                                                                                                                                                                                                                                                                How to keep your privacy in mobile apps

                                                                                                                                                                                                                                                                                                  Couple years ago, I worked on a mobile app linked to video and audio recording. I quickly see that, once the user agreed for permissions, it can be easy to track personal data without user noticed it. Let see how limit mobile app permissions to maintain user privacy.

                                                                                                                                                                                                                                                                                                  Appium, when automation testing can be randomly wrong

                                                                                                                                                                                                                                                                                                    Appium is an UI automation testing framework, helping developers to automatically test their app. This tool can be really powerful but my experience with it let me think it’s not enough accurate to be used everyday and at its full potential.

                                                                                                                                                                                                                                                                                                    UI Automation testing on iOS9

                                                                                                                                                                                                                                                                                                      During WWDC2015, Apple announced big stuff, but they also released awesome features for developers. One of them was dedicated to UI Testing. Working around UI Automation test, I’ve just discovered last Xcode 7 and how life is going to be easier with their last feature for that.

                                                                                                                                                                                                                                                                                                      How to work with native iOS and javascript callbacks in Objective-C

                                                                                                                                                                                                                                                                                                        Recently I worked on a small iOS mobile project around Javascript. I wanted to load web content from iOS with Javascript inside and get callbacks from Javascript into iOS, to save native data and transmit it to an other controller if needed. The second part was also to call Javascript methods from iOS part.

                                                                                                                                                                                                                                                                                                        AmbiMac, an app creating your own ambilight

                                                                                                                                                                                                                                                                                                          Philips created few years ago Ambilight, a TV with a dynamic lights on it back. With two friends, we wanted to design an app with a similar function based on connected light bulb during an hackathon. Here is what we have done in 24h hours of code, let’s meet AmbiMac.

                                                                                                                                                                                                                                                                                                          Introduction to sleep analysis with HealthKit with Swift

                                                                                                                                                                                                                                                                                                            HealthKit is a powerful tool if you want to create an iOS mobile app based on health data. However, it’s not only for body measurements, fitness or nutrition; it’s also sleep analysis. In this HealthKit tutorial, I will show you how to read and write some sleep data and save them in Health app.

                                                                                                                                                                                                                                                                                                            UPDATE - April 2020: Originally written for Swift 1.0, then 2.0, I’ve updated this post for latest Swift 5.1 version and Xcode 11.3.

                                                                                                                                                                                                                                                                                                            Dynamic url rewriting in CodeIgniter

                                                                                                                                                                                                                                                                                                              I work with CodeIgniter almost exclusively on API, but sometimes it can help on short-lived websites. Rewrite url is a good thing to know if you want to optimize SEO for your key pages of a website. That’s what I want to show you and how it’s easy to set it up.

                                                                                                                                                                                                                                                                                                              Le métier de développeur dans les objets connectés

                                                                                                                                                                                                                                                                                                                Pour la fin de mes études, j’ai choisi de rédiger mon mémoire sur les objets connectés et plus précisément sur le développement de services numériques autour de ces objets. Ce travail de fond m’a permis de prendre du recul sur mon travail mais c’était aussi l’occasion de trouver une définition de ce qu’est un développeur d’objet connecté.

                                                                                                                                                                                                                                                                                                                Majordhome, le projet né durant un startup weekend

                                                                                                                                                                                                                                                                                                                  En Octobre dernier, j’avais travaillé sur le cocktailMaker, un objet connecté facilitant la création de cocktails. Voulant pousser le concept un peu plus loin, je me suis inscrit au startup weekend de Novembre organisé à l’EM Lyon pour découvrir les aspects marketing et business qui me manque aujourd’hui. Retour sur ces 54h de travail acharné.

                                                                                                                                                                                                                                                                                                                  Les difficultés autour des objets connectés

                                                                                                                                                                                                                                                                                                                    Ces temps ci, il y a beaucoup de bruits autour des objets connectés. Tous les jours, on découvre de nouveaux articles sur des objets connectés annoncés sur le marché ou financés sur des plateformes de “crowdfunding”. On a bien moins d’informations sur toutes les difficultés liées autour de ces projets innovants. Voici mes conclusions sur les recherches que j’ai faites à ce sujet.

                                                                                                                                                                                                                                                                                                                    CocktailMaker, l'objet connecté 100% hackathon

                                                                                                                                                                                                                                                                                                                      L’année dernière à cette même période, j’ai participé au Fhacktory, ce hackathon nouvelle génération né à Lyon, avec une application mobile dédiée à la chute libre. Cette année, j’ai pu à nouveau monter sur le podium de cet évènement en développement un objet connecté, le CocktailMaker. Retour sur ce week-end 100% hack.

                                                                                                                                                                                                                                                                                                                      Comment Jawbone s'adapte à l'Internet des Choses

                                                                                                                                                                                                                                                                                                                        Sur la place des objets connectés, Jawbone est rapidement devenu un pilier du “quantified-self” (auto-mesure) avec ses bracelets UP et UP24. Je vous propose un décryptage des leurs dernières évolutions afin de rester à la pointe du “wearable”.

                                                                                                                                                                                                                                                                                                                        Moto360 ou Withings Activité

                                                                                                                                                                                                                                                                                                                          De plus en plus de montres connectées font leur apparition, mais d’après moi, la plupart passe à côté de l’essentiel: la montre reste l’un des seuls accessoires masculin, il faut donc la rendre élégante en respectant sa forme historique. C’est pourquoi, je m’intéresse dans cet article principalement aux montres “habillées” et en attendant la sortie de celle d’Apple, je vous propose un comparatif entre la montre connectée de Motorola et celle de Withings, fraichement annoncée.

                                                                                                                                                                                                                                                                                                                          Mes premiers pas vers le Lean Startup

                                                                                                                                                                                                                                                                                                                            Ne voulant pas me limiter à mon background technique, j’essaie de plus en plus de développer des notions d’entrepreneuriat dans l’idée d’être plus utile dans mon analyse technique et de continuer la reflexion autour de différents développement d’applications dans une start-up. L’idée est de ne pas se limiter au développement demandé, mais d’essayer d’appréhender toute la chaine de réflexion, à savoir du besoin de clients jusqu’à l’utilisation d’un nouveau service/produit développé et de voir comment celui-ci est utilisé et ce qu’il faut améliorer.

                                                                                                                                                                                                                                                                                                                            Pour cela, et avec les conseils avisés d’un ami , Maxime Salomon, j’ai commencé à lire The Lean Startup de Eric Ries. Ce livre aborde de nombreux sujets autour de l’entrepreneuriat, du marketing ainsi que de développement de produit à proprement parlé. L’idée est de proposer un cycle itératif de développement pouvant permettre de mesurer rapidement différents paramètres pour faire évoluer un produit en fonction de nouvelles données.

                                                                                                                                                                                                                                                                                                                            Etant d’un formation plus scientifique, j’ai ce besoin de mettre en pratique ce dont il est question pour mieux comprendre la solution proposée, j’ai aussi un besoin de me documenter sur les différents termes employés pour ne pas passer à côté du sujet, c’est pourquoi je prends mon temps pour lire ce livre, mais je vous propose mon retour d’expérience sur mes premiers acquis et comment j’essaie de les mettre en pratique.

                                                                                                                                                                                                                                                                                                                            UP24 - Découverte du bracelet connecté de Jawbone

                                                                                                                                                                                                                                                                                                                              Nous découvrons chaque jour de plus en plus d’objets connectés, ils se divisent en plusieurs catégories comme la santé, la musique, la lumière, etc. Une bonne partie se retrouve aussi dans le tracking d’activité comme le bracelet Jawbone UP. Etant intéressé de connaitre les performances de ces objets connectés dit “wearable”, je vous propose mon retour d’experience sur le bracelet UP24 ainsi que les services proposés autour.

                                                                                                                                                                                                                                                                                                                              Introduction à Soundcloud

                                                                                                                                                                                                                                                                                                                                Soundcloud est une des plus grosses plateformes de musique indépendante, c’est plus de 200 millions d’utilisateurs pour ce réseau sociale basé sur le partage musicale. Certains artistes ne publient leurs musiques que sur cette plateforme. C’est aussi la place pour des novices qui veulent essayer leurs titres et se faire connaitre. Vous pouvez aussi  y retrouver des discours, des podcasts et tout autres types de contenu audio.

                                                                                                                                                                                                                                                                                                                                Dans cette optique de toujours avoir de la bonne musique, Soundcloud est disponible sur toutes les plateformes (web et mobile) et l’écoute est gratuite. Pour une utilisation encore plus variée de leur service, SoundCloud propose une API ainsi que de nombreux SDK (Javascript, Ruby, Python, PHP, Cocoa et Java). Nous allons voir ensemble comment intégrer SoundCloud dans une application mobile iPhone.

                                                                                                                                                                                                                                                                                                                                Comment réussir son premier entretien

                                                                                                                                                                                                                                                                                                                                  Passer un entretien pour un poste est toujours un peu stressant. Suivant comment ce stress est géré, la personne peut donner une image de quelqu’un qui n’est pas sûre de soi par ses gestes (tremblement, bafouillement, se frotter les mains) ou par ses mots (ne pas finir ses phrases, phrases à rallonge trop complexe, etc). Difficile dans ces cas là de donner la meilleure image de soi pour montrer qu’on est travailleur, motivé et prêt à l’emploi.

                                                                                                                                                                                                                                                                                                                                  Je vous propose par mon retour d’experience quelques conseils simples.

                                                                                                                                                                                                                                                                                                                                  Spotify et ses outils d'intégration

                                                                                                                                                                                                                                                                                                                                    Après avoir travaillé avec les technologies Deezer, nous allons voir quels outils sont proposés par Spotify pour une intégration web ou mobile. Spotify proposant une écoute gratuite sur son client ordinateur et depuis peu sur mobile (parsemé de publicité), il se démarque de Deezer qui nécessite d’avoir un compte Premium pour une utilisation sur smartphone.  L’intégration pour les développeurs est aussi différente, mais à quelle mesure? C’est ce que nous allons voir.

                                                                                                                                                                                                                                                                                                                                    Hackathon: ma maison connectėe

                                                                                                                                                                                                                                                                                                                                      Les objets connectės sont de plus en plus présents chez nous. On y retrouve des produits comme des ampoules, des enceintes audio ainsi que des prises intelligentes. On y retrouve aussi des produits plus innovants comme le pèse personne de Withings, la balle de Sphero, la lampe connectée “holî” ou encore le capteur pour plante de Parrot.

                                                                                                                                                                                                                                                                                                                                      C’est dans cette optique là que l’entreprise Direct Energie a organisée un hackathon autour des objets connectés pour présenter différentes solutions autour de la maîtrise d’énergie et des objets intelligents.

                                                                                                                                                                                                                                                                                                                                      C’est en tant que support technique sur le produit “holî” et son SDK que j’y ai participé, afin d’aider les développeurs à se familiariser avec l’outil. Ayant fait un hackathon du côté développeur, c’est un nouveau retour d’expérience cette fois ci du côté partenaire.

                                                                                                                                                                                                                                                                                                                                      SpriteKit, un framework iOS7 pour jeu video

                                                                                                                                                                                                                                                                                                                                        Au jour d’aujourd’hui, les jeux vidéos sont de plus en plus présent. Avec l’univers du smartphone, il est de plus en plus facile d’embarquer des jeux vidéos avec nous et ce partout.

                                                                                                                                                                                                                                                                                                                                        Plusieurs jeux ont eu un tel succès qu’il reste difficile d’ignorer cet utilisation de nos téléphones en tant que console. A n’en citer que quelques-uns: DoodleJump, AngryBird ou encore le fameux CandyCrush.

                                                                                                                                                                                                                                                                                                                                        Depuis la sortie d’iOS7, Apple a rajouté un framework de jeu vidéo 2D directement dans son SDK: SpriteKit. Nous allons voir ensemble comment l’utiliser.

                                                                                                                                                                                                                                                                                                                                        Fhacktory, un hackathon nouvelle génération

                                                                                                                                                                                                                                                                                                                                          Un hackathon est l’équivalent d’un marathon sur le domaine du développement informatique. Bien connu sous le système de “Startup Weekend”, ce principe a été adapté dans l’informatique au développement de projet en un temps donné. Le but est de monter en un weekend une équipe qui évoluera autour d’une idée et proposera une solution à un problème. J’ai récemment participé à l’un d’entre eux, le Fhactory: un hackathon se définissant “100% hack, 0% bullshit” et voici mon retour d’expérience.

                                                                                                                                                                                                                                                                                                                                          À la découverte des outils de Deezer

                                                                                                                                                                                                                                                                                                                                            Deezer étant l’une des plus grosse plateforme d’écoute et de partage de musique, il est intéressant de voir comment se servir des différents outils qu’il nous met à disposition à savoir son API de recherche de morceau et ses différents SDK pour une intégration web ou mobile.

                                                                                                                                                                                                                                                                                                                                            Nous allons voir ensemble, comment les utiliser, à quelles fins et quelles en sont les limites. Pour le SDK, je ne m’intéresserai qu’à celui pour iOS.

                                                                                                                                                                                                                                                                                                                                            iJump, une application iPhone pour les parachutistes

                                                                                                                                                                                                                                                                                                                                              En lançant le portail web de météo Weather, mon idée était d’en faire un support pour une version mobile. En effet l’intérêt pour des données météorologiques est de rester nomade et suivre son utilisateur. En intégrant différentes notions associées à la chute libre et avec l’aide de la Fédération Française de Parachutisme, voici iJump: l’application mobile pour les parachutistes.

                                                                                                                                                                                                                                                                                                                                              La formation au développement mobile

                                                                                                                                                                                                                                                                                                                                                Il y a maintenant 6 mois, j’ai commencé une formation afin de devenir enseignant sur les languages Cocoa et Objective-C.

                                                                                                                                                                                                                                                                                                                                                Cette formation a compris plusieurs étapes, chacune finissant par un examen afin de passer à la suivante:

                                                                                                                                                                                                                                                                                                                                                • Une partie pédagogique au cours de laquelle nous sommes évalués sur notre capacité à communiquer un message, à faire comprendre une technologie, à la gestion de notre temps de parole ainsi qu’à la tenue une classe.
                                                                                                                                                                                                                                                                                                                                                • Une partie technique où l’évaluation se portait exclusivement sur la connaissance des technologies auxquelles je m’étais proposé. Pour ma part, cela m’a permis de revoir les fondements de Cocoa ainsi que de l’historique la société NeXT.

                                                                                                                                                                                                                                                                                                                                                Voici mes différents retours sur ma première experience de formateur.

                                                                                                                                                                                                                                                                                                                                                Sencha Touch: framework HTML5 pour application mobile

                                                                                                                                                                                                                                                                                                                                                  Introduction:

                                                                                                                                                                                                                                                                                                                                                  Sencha est un framework HTML5 pour créer des application mobiles multiplateformes. L’intérêt de celui-ci est de faire, à partir d’un projet HTML et de code JSON, une même application mobile sur plusieurs plateformes, un gain de temps incroyable si le code s’y tient. Nous allons voir les premiers pas d’une application à partir de Sencha.

                                                                                                                                                                                                                                                                                                                                                  MVVM Light sous Windows Phone 8 SDK

                                                                                                                                                                                                                                                                                                                                                    Le nouveau système d’exploitation Windows 8 va de paire avec la mise à jour de son système sur mobile: Windows Phone 8.

                                                                                                                                                                                                                                                                                                                                                    Voici une petite introduction à MVVM Light Toolkit, un jeu de composant se basant sur une structure Model-View-ViewModel sur les frameworks XAML/C#,  pouvant être utilisé pour un développement sur Windows Phone 8.

                                                                                                                                                                                                                                                                                                                                                    Réalisation: Weather, un portail météo pour la chute libre

                                                                                                                                                                                                                                                                                                                                                      Contexte:

                                                                                                                                                                                                                                                                                                                                                      Ayant récemment été initié à la chute libre, cette discipline est largement dépendante de la météo.

                                                                                                                                                                                                                                                                                                                                                      Malheureusement, trouver la météo en temps en “temps réel” suivant son centre de saut n’est pas chose aisé. Même à 10km de son centre de saut, la différence météorologique peut être significative quant à la pratique du parachutisme.

                                                                                                                                                                                                                                                                                                                                                      C’est pourquoi j’ai décidé de developper un portail web permettant de consulter le dernier relevé météo de n’importe quel centre de saut en France, datant de moins de 12h.

                                                                                                                                                                                                                                                                                                                                                      Intégration de DataMapper dans CodeIgniter

                                                                                                                                                                                                                                                                                                                                                        Introduction:

                                                                                                                                                                                                                                                                                                                                                        Un ORM (Object-relational mapping) est utilisé dans la programmation orienté objet afin de créer virtuellement un modèle en se basant sur une base de donnée. Cela évite de devoir écrire les requêtes dans la base de donnée soit même, un vrai gain de temps.

                                                                                                                                                                                                                                                                                                                                                        Réalisation: iDevWeb - Mise à jour

                                                                                                                                                                                                                                                                                                                                                          Librairie Restkit et synchronisation de données

                                                                                                                                                                                                                                                                                                                                                            Introduction

                                                                                                                                                                                                                                                                                                                                                            La synchronisation de données en ligne est une pratique courante afin d’avoir un contenu mis à jour à chaque utilisation (applications d’informations, de news et autres).

                                                                                                                                                                                                                                                                                                                                                            Trouver un moyen simple d’embarquer ces données avant une synchronisation en ligne est intéressant, permettant une utilisation de l’application même si les données ne sont pas à jour.

                                                                                                                                                                                                                                                                                                                                                            Travaillant en Objective-C sur des applications mobiles pour iphone/ipad, nous allons voir comment utiliser Restkit à ces fins.

                                                                                                                                                                                                                                                                                                                                                            Quel-camping.fr

                                                                                                                                                                                                                                                                                                                                                              Après avoir fini ma première année d’étude en informatique, j’ai eu l’idée de réaliser un site internet pour une première experience professionnelle à mon compte.

                                                                                                                                                                                                                                                                                                                                                              Des idées à l’étude:

                                                                                                                                                                                                                                                                                                                                                              Après quelques idées ainsi que des conseils avisés d’un jeune entrepreneur, j’ai décidé de choisir la branche du tourisme et plus précisément le domaine de l’hotellerie de plein air.

                                                                                                                                                                                                                                                                                                                                                              En effet, ce domaine est peu exploité sur internet alors que le nombre de réservation de séjour en camping continuait d’augmenter.

                                                                                                                                                                                                                                                                                                                                                              Réalisation: iDevWeb - Gestion de projets web

                                                                                                                                                                                                                                                                                                                                                                Quand on est développeur web, il arrive qu’on travaille sur plusieurs projets en même temps et qu’on conserve d’anciens projets sans les supprimer.

                                                                                                                                                                                                                                                                                                                                                                En utilisant MAMP sous MAC OS X, il faut accéder à l’url exacte du dossier pour pouvoir accéder au site web, il n’existe pas par défaut une page qui indexe les dossiers contenus dans le dossier de développement.

                                                                                                                                                                                                                                                                                                                                                                C’est là que j’ai eu l’idée de développer un petit portail en php qui listerait les dossiers contenus dans mon dossier de développement, cela éviterait de devoir se rappeler du nom du projet ainsi que du chemin exacte pour y accéder.

                                                                                                                                                                                                                                                                                                                                                                Réécriture d'urls avec htaccess sous CodeIgniter

                                                                                                                                                                                                                                                                                                                                                                  Le principe de réécriture d’urls permet de “transformer” les urls pour référencer plus simplement des pages clés d’un site internet. Pour cela on utilise le fichier htaccess, un fichier caché situé à la racine du dossier de l’application.

                                                                                                                                                                                                                                                                                                                                                                  Nous allons voir comment est géré par défaut les urls dans le framework CodeIgniter et comment les modifier pour éviter de perdre le référencement déjà acquis sur un site web.

                                                                                                                                                                                                                                                                                                                                                                  CodeIgniter et son modèle MVC

                                                                                                                                                                                                                                                                                                                                                                    CodeIgniter est un framework php open source basé sur une architecture MVC.

                                                                                                                                                                                                                                                                                                                                                                    Rappel:

                                                                                                                                                                                                                                                                                                                                                                    L’architecture MVC (Modèle – Vue – Controller) permet d’organiser plus simplement une application.

                                                                                                                                                                                                                                                                                                                                                                    • Modèle : type de données, objet
                                                                                                                                                                                                                                                                                                                                                                    • Vue: interface avec l’utilisateur
                                                                                                                                                                                                                                                                                                                                                                    • Contrôleur: traitement des données, gestion des évènements.

                                                                                                                                                                                                                                                                                                                                                                    Un framework est un kit qui permet de créer la base d’une application plus rapidement et avec une structure plus solide.

                                                                                                                                                                                                                                                                                                                                                                    Présentation:

                                                                                                                                                                                                                                                                                                                                                                    CodeIgniter a pour avantage d’être libre mais surtout d’être plus léger comparé aux autres frameworks php connus. Il possède un “guide utilisateur” (en ligne sur le site officiel et localement dans le dossier téléchargé) plus que complet qui propose de nombreux exemples d’applications. La mise en place est intuitive et aucune configuration n’est nécessaire pour une utilisation simple.

                                                                                                                                                                                                                                                                                                                                                                    Tips, Tricks, and Techniques on using Cascading Style Sheets.

                                                                                                                                                                                                                                                                                                                                                                    Worlds Collide: Keyframe Collision Detection Using Style Queries

                                                                                                                                                                                                                                                                                                                                                                    • Articles
                                                                                                                                                                                                                                                                                                                                                                    • Scroll Driven Animation
                                                                                                                                                                                                                                                                                                                                                                    • Style Queries

                                                                                                                                                                                                                                                                                                                                                                    Interactive CSS animations with elements ricocheting off each other seem more plausible in 2025. While it’s unnecessary to implement Pong in CSS, the increasing flexibility and power of CSS reinforce Lee's suspicion that one day it will be a lifestyle choice whether to achieve any given effect with scripting or CSS.

                                                                                                                                                                                                                                                                                                                                                                    Worlds Collide: Keyframe Collision Detection Using Style Queries originally published on CSS-Tricks, which is part of the DigitalOcean family. You should get the newsletter.

                                                                                                                                                                                                                                                                                                                                                                    A friend DMs Lee Meyer a CodePen by Manuel Schaller containing a pure CSS simulation of one of the world’s earliest arcade games, Pong, with both paddles participating automatically, in an endless loop. The demo reminds Lee of an arcade machine in attract mode awaiting a coin, and the iconic imagery awakens muscle memory from his misspent childhood, causing him to search his pocket in which he finds the token a spooky shopkeeper gave him last year at the CSS tricks stall in the haunted carnival. The token gleams like a power-up in the light of his laptop, which has a slot he never noticed. He feeds the token into the slot, and the CodePen reloads itself. A vertical range input and a life counter appear, allowing him to control the left paddle and play the game in Chrome using a cocktail of modern and experimental CSS features to implement collision detection in CSS animations. He recalls the spooky shopkeeper’s warning that playing with these features has driven some developers to madness, but the shopkeeper’s voice in Lee’s head whispers: “Too late, we are already playing.” CSS collision detection: Past and present So, maybe the experience of using modern CSS to add collision detection and interactivity to an animation wasn’t as much like a screenplay sponsored by CSS as I depicted in the intro above — but it did feel like magic compared to what Alex Walker had to go through in 2013 to achieve a similar effect. Hilariously, he describes his implementation as “a glittering city of hacks built on the banks of the ol’ Hack River. On the Planet Hack.“ Alex’s version of CSS Pong cleverly combines checkbox hacks, sibling selectors, and :hover, whereas the CodePen below uses style queries to detect collisions. I feel it’s a nice illustration of how far CSS has come, and a testament to increased power and expressiveness of CSS more than a decade later. It shows how much power we get when combining new CSS features — in this case, that includes style queries, animatable custom properties, and animation timelines. The future CSS features of inline conditionals and custom functions might be able to simplify this code more. CodePen Embed Fallback Collision detection with style queries Interactive CSS animations with elements ricocheting off each other seems more plausible in 2025 and the code is somewhat sensible. While it’s unnecessary to implement Pong in CSS, and the CSS Working Group probably hasn’t been contemplating how to make that particular niche task easier, the increasing flexibility and power of CSS reinforce my suspicion that one day it will be a lifestyle choice whether to achieve any given effect with scripting or CSS. The demo is a similar number of lines of CSS to Alex’s 2013 implementation, but it didn’t feel much like a hack. It’s a demo of modern CSS features working together in the way I expected after reading the instruction booklet. Sometimes when reading introductory articles about the new features we are getting in CSS, it’s hard to appreciate how game-changing they are till you see several features working together. As often happens when pushing the boundaries of a technology, we are going to bump up against the current limitations of style queries and animations. But it’s all in good fun, and we’ll learn about these CSS features in more detail than if we had not attempted this crazy experiment. It does seem to work, and my 12-year-old and 7-year-old have both playtested it on my phone and laptop, so it gets the “works on Lee’s devices” seal of quality. Also, since Chrome now supports controlling animations using range inputs, we can make our game playable on mobile, unlike the 2013 version, which relied on :hover. Temani Afif provides a great explanation of how and why view progress timelines can be used to style anything based on the value of a range input. Using style queries to detect if the paddle hit the ball The ball follows a fixed path, and whether the player’s paddle intersects with the ball when it reaches our side is the only input we have into whether it continues its predetermined bouncy loop or the screen flashes red as the life counter goes down till we see the “Game Over” screen with the option to play again. This type of interactivity is what game designers call a quick time event. It’s still a game for sure, but five months ago, when I was young and naive, I mused in my article on animation timelines that the animation timeline feature could open the door for advanced games and interactive experiences in CSS. I wrote that a video game is just a “hyper-interactive animation.” Indeed, the above experiment shows that the new features in CSS allow us to respond to user input in sophisticated ways, but the demo also clarifies the difference between the kind of interactivity we can expect from the current incarnation of CSS versus scripting. The above experiment is more like if Pong were a game inside the old-school arcade game Dragon’s Lair, which was one giant quick time event. It only works because there are limited possible outcomes, but they are certainly less limited than what we used to be able to achieve in CSS. Since we know collision detection with the paddle is the only opportunity for the user to have a say in what happens next, let’s focus on that implementation. It will require more mental gymnastics than I would like, since container style queries only allow for name-value pairs with the same syntax as feature queries, meaning we can’t use “greater than” or “less than” operators when comparing numeric values like we do with container size queries which follow the same syntax as @media size queries. The workaround below allows us to create style queries based on the ball position being in or out of the range of the paddle. If the ball hits our side, then by default, the play field will flash red and temporarily unpause the animation that decrements the life counter (more on that later). But if the ball hits our side and is within range of the paddle, we leave the life-decrementing animation paused, and make the field background green while the ball hits the paddle. Since we don’t have “greater than” or “less than” operators in style queries, we (ab)use the min() function. If the result equals the first argument then that argument is less than or equal to the second; otherwise it’s greater than the second argument. It’s logical but made me wish for better comparison operators in style queries. Nevertheless, I was impressed that style queries allow the collision detection to be fairly readable, if a little more verbose than I would like. body { --int-ball-position-x: round(down, var(--ball-position-x)); --min-ball-position-y-and-top-of-paddle: min(var(--ball-position-y) + var(--ball-height), var(--ping-position)); --min-ball-position-y-and-bottom-of-paddle: min(var(--ball-position-y), var(--ping-position) + var(--paddle-height)); } @container style(--int-ball-position-x: var(--ball-left-boundary)) { .screen { --lives-decrement: running; .field { background: red; } } } @container style(--min-ball-position-y-and-top-of-paddle: var(--ping-position)) and style(--min-ball-position-y-and-bottom-of-paddle: var(--ball-position-y)) and style(--int-ball-position-x: var(--ball-left-boundary)) { .screen { --lives-decrement: paused; .field { background: green; } } } Responding to collisions Now that we can style our playing field based on whether the paddle hits the ball, we want to decrement the life counter if our paddle misses the ball, and display “Game Over” when we run out of lives. One way to achieve side effects in CSS is by pausing and unpausing keyframe animations that run forwards. These days, we can style things based on custom properties, which we can set in animations. Using this fact, we can take the power of paused animations to another level. body { animation: ball 8s infinite linear, lives 80ms forwards steps(4) var(--lives-decrement); --lives-decrement: paused; } .lives::after { content: var(--lives); } @keyframes lives { 0% { --lives: "3"; } 25% { --lives: "2"; } 75% { --lives: "1"; } 100% { --lives: "0"; } } @container style(--int-ball-position-x: var(--ball-left-boundary)) { .screen { --lives-decrement: running; .field { background: red; } } } @container style(--min-ball-position-y-and-top-of-paddle: var(--ping-position)) and style(--min-ball-position-y-and-bottom-of-paddle: var(--ball-position-y)) and style(--int-ball-position-x: 8) { .screen { --lives-decrement: paused; .field { background: green; } } } @container style(--lives: '0') { .field { display: none; } .game-over { display: flex; } } So when the ball hits the wall and isn’t in range of the paddle, the lives-decrementing animation is unpaused long enough to let it complete one step. Once it reaches zero we hide the play field and display the “Game Over” screen. What’s fascinating about this part of the experiment is that it shows that, using style queries, all properties become indirectly possible to control via animations, even when working with non-animatable properties. And this applies to properties that control whether other animations play. This article touches on why play state deliberately isn’t animatable and could be dangerous to animate, but we know what we are doing, right? Full disclosure: The play state approach did lead to hidden complexity in the choice of duration of the animations. I knew that if I chose too long a duration for the life-decrementing counter, it might not have time to proceed to the next step while the ball was hitting the wall, but if I chose too short a duration, missing the ball once might cause the player to lose more than one life. I made educated guesses of suitable durations for the ball bouncing and life decrementing, and I expected that when working with fixed-duration predictable animations, the life counter would either always work or always fail. I didn’t expect that my first attempt at the implementation intermittently failed to decrement the life counter at the same point in the animation loop. Setting the durations of both these related animations to multiples of eight seems to fix the problem, but why would predetermined animations exhibit unpredictable behavior? Forefeit the game before somebody else takes you out of the frame I have theories as to why the unpredictability of the collision detection seemed to be fixed by setting the ball animation to eight seconds and the lives animation to 80 milliseconds. Again, pushing CSS to its limits forces us to think deeper about how it’s working. CSS appears to suffer from timer drift, meaning if you set a keyframes animation to last for one second, it will sometimes take slightly under or over one second. When there is a different rate of change between the ball-bouncing and life-losing, it would make sense that the potential discrepancy between the two would be pronounced and lead to unpredictable collision detection. When the rate of change in both animations is the same, they would suffer about equally from timer drift, meaning the frames still synchronize predictably. Or at least I’m hoping the chance they don’t becomes negligible. Alex’s 2013 version of Pong uses translate3d() to move the ball even though it only moves in 2D. Alex recommends this whenever possible “for efficient animation rendering, offloading processing to the GPU for smoother visual effects.” Doing this may have been an alternative fix if it leads to more precise animation timing. There are tradeoffs so I wasn’t willing to go down that rabbit hole of trying to tune the animation performance in this article — but it could be an interesting focus for future research into CSS collision detection. Maybe style queries take a varying amount of time to kick in, leading to some form of a race condition. It is possible that making the ball-bouncing animation slower made this problem less likely. Maybe the bug remains lurking in the shadows somewhere. What did I expect from a hack I achieved using a magic token from a spooky shopkeeper? Haven’t I seen any eighties movie ever? Outro You finish reading the article, and feel sure that the author’s rationale for his supposed fix for the bug is hogwash. Clearly, Lee has been driven insane by the allure of overpowering new CSS features, whereas you respect the power of CSS, but you also respect its limitations. You sit down to spend a few minutes with the collision detection CodePen to prove it is still broken, but then find other flaws in the collision detection, and you commence work on a fork that will be superior. Hey, speaking of timer drift, how is it suddenly 1 a.m.? Only a crazy person would stay up that late playing with CSS when they have to work the next day. “Madness,” repeats the spooky shopkeeper inside your head, and his laughter echoes somewhere in the night. Roll the credits This looping Pong CSS animation by Manuel Schaller gave me an amazing basis for adding the collision detection. His twitching paddle animations help give the illusion of playing against a computer opponent, so forking his CodePen let me focus on implementing the collision detection rather than reinventing Pong. This author is grateful to the junior testing team, comprised of his seven-year-old and twelve-year-old, who declared the CSS Pong implementation “pretty cool.” They also suggested the green and red flashes to signal collisions and misses. The intro and outro for this article were sponsored by the spooky shopkeeper who sells dangerous CSS tricks. He also sells frozen yoghurt, which he calls froghurt. Worlds Collide: Keyframe Collision Detection Using Style Queries originally published on CSS-Tricks, which is part of the DigitalOcean family. You should get the newsletter.

                                                                                                                                                                                                                                                                                                                                                                    Automated Visual Regression Testing With Playwright

                                                                                                                                                                                                                                                                                                                                                                    • Articles
                                                                                                                                                                                                                                                                                                                                                                    • testing

                                                                                                                                                                                                                                                                                                                                                                    With visual regression testing, we can update a page, take screenshots before and after the fact, and compare the results for unintended changes. In this article, learn how to set up visual regression testing using Playwright.

                                                                                                                                                                                                                                                                                                                                                                    Automated Visual Regression Testing With Playwright originally published on CSS-Tricks, which is part of the DigitalOcean family. You should get the newsletter.

                                                                                                                                                                                                                                                                                                                                                                    Comparing visual artifacts can be a powerful, if fickle, approach to automated testing. Playwright makes this seem simple for websites, but the details might take a little finessing. Recent downtime prompted me to scratch an itch that had been plaguing me for a while: The style sheet of a website I maintain has grown just a little unwieldy as we’ve been adding code while exploring new features. Now that we have a better idea of the requirements, it’s time for internal CSS refactoring to pay down some of our technical debt, taking advantage of modern CSS features (like using CSS nesting for more obvious structure). More importantly, a cleaner foundation should make it easier to introduce that dark mode feature we’re sorely lacking so we can finally respect users’ preferred color scheme. However, being of the apprehensive persuasion, I was reluctant to make large changes for fear of unwittingly introducing bugs. I needed something to guard against visual regressions while refactoring — except that means snapshot testing, which is notoriously slow and brittle. In this context, snapshot testing means taking screenshots to establish a reliable baseline against which we can compare future results. As we’ll see, those artifacts are influenced by a multitude of factors that might not always be fully controllable (e.g. timing, variable hardware resources, or randomized content). We also have to maintain state between test runs, i.e. save those screenshots, which complicates the setup and means our test code alone doesn’t fully describe expectations. Having procrastinated without a more agreeable solution revealing itself, I finally set out to create what I assumed would be a quick spike. After all, this wouldn’t be part of the regular test suite; just a one-off utility for this particular refactoring task. Fortunately, I had vague recollections of past research and quickly rediscovered Playwright’s built-in visual comparison feature. Because I try to select dependencies carefully, I was glad to see that Playwright seems not to rely on many external packages. Setup The recommended setup with npm init playwright@latest does a decent job, but my minimalist taste had me set everything up from scratch instead. This do-it-yourself approach also helped me understand how the different pieces fit together. Given that I expect snapshot testing to only be used on rare occasions, I wanted to isolate everything in a dedicated subdirectory, called test/visual; that will be our working directory from here on out. We’ll start with package.json to declare our dependencies, adding a few helper scripts (spoiler!) while we’re at it: { "scripts": { "test": "playwright test", "report": "playwright show-report", "update": "playwright test --update-snapshots", "reset": "rm -r ./playwright-report ./test-results ./viz.test.js-snapshots || true" }, "devDependencies": { "@playwright/test": "^1.49.1" } } If you don’t want node_modules hidden in some subdirectory but also don’t want to burden the root project with this rarely-used dependency, you might resort to manually invoking npm install --no-save @playwright/test in the root directory when needed. With that in place, npm install downloads Playwright. Afterwards, npx playwright install downloads a range of headless browsers. (We’ll use npm here, but you might prefer a different package manager and task runner.) We define our test environment via playwright.config.js with about a dozen basic Playwright settings: import { defineConfig, devices } from "@playwright/test"; let BROWSERS = ["Desktop Firefox", "Desktop Chrome", "Desktop Safari"]; let BASE_URL = "http://localhost:8000"; let SERVER = "cd ../../dist && python3 -m http.server"; let IS_CI = !!process.env.CI; export default defineConfig({ testDir: "./", fullyParallel: true, forbidOnly: IS_CI, retries: 2, workers: IS_CI ? 1 : undefined, reporter: "html", webServer: { command: SERVER, url: BASE_URL, reuseExistingServer: !IS_CI }, use: { baseURL: BASE_URL, trace: "on-first-retry" }, projects: BROWSERS.map(ua => ({ name: ua.toLowerCase().replaceAll(" ", "-"), use: { ...devices[ua] } })) }); Here we expect our static website to already reside within the root directory’s dist folder and to be served at localhost:8000 (see SERVER; I prefer Python there because it’s widely available). I’ve included multiple browsers for illustration purposes. Still, we might reduce that number to speed things up (thus our simple BROWSERS list, which we then map to Playwright’s more elaborate projects data structure). Similarly, continuous integration is YAGNI for my particular scenario, so that whole IS_CI dance could be discarded. Capture and compare Let’s turn to the actual tests, starting with a minimal sample.test.js file: import { test, expect } from "@playwright/test"; test("home page", async ({ page }) => { await page.goto("/"); await expect(page).toHaveScreenshot(); }); npm test executes this little test suite (based on file-name conventions). The initial run always fails because it first needs to create baseline snapshots against which subsequent runs compare their results. Invoking npm test once more should report a passing test. Changing our site, e.g. by recklessly messing with build artifacts in dist, should make the test fail again. Such failures will offer various options to compare expected and actual visuals: We can also inspect those baseline snapshots directly: Playwright creates a folder for screenshots named after the test file (sample.test.js-snapshots in this case), with file names derived from the respective test’s title (e.g. home-page-desktop-firefox.png). Generating tests Getting back to our original motivation, what we want is a test for every page. Instead of arduously writing and maintaining repetitive tests, we’ll create a simple web crawler for our website and have tests generated automatically; one for each URL we’ve identified. Playwright’s global setup enables us to perform preparatory work before test discovery begins: Determine those URLs and write them to a file. Afterward, we can dynamically generate our tests at runtime. While there are other ways to pass data between the setup and test-discovery phases, having a file on disk makes it easy to modify the list of URLs before test runs (e.g. temporarily ignoring irrelevant pages). Site map The first step is to extend playwright.config.js by inserting globalSetup and exporting two of our configuration values: export let BROWSERS = ["Desktop Firefox", "Desktop Chrome", "Desktop Safari"]; export let BASE_URL = "http://localhost:8000"; // etc. export default defineConfig({ // etc. globalSetup: require.resolve("./setup.js") }); Although we’re using ES modules here, we can still rely on CommonJS-specific APIs like require.resolve and __dirname. It appears there’s some Babel transpilation happening in the background, so what’s actually being executed is probably CommonJS? Such nuances sometimes confuse me because it isn’t always obvious what’s being executed where. We can now reuse those exported values within a newly created setup.js, which spins up a headless browser to crawl our site (just because that’s easier here than using a separate HTML parser): import { BASE_URL, BROWSERS } from "./playwright.config.js"; import { createSiteMap, readSiteMap } from "./sitemap.js"; import playwright from "@playwright/test"; export default async function globalSetup(config) { // only create site map if it doesn't already exist try { readSiteMap(); return; } catch(err) {} // launch browser and initiate crawler let browser = playwright.devices[BROWSERS[0]].defaultBrowserType; browser = await playwright[browser].launch(); let page = await browser.newPage(); await createSiteMap(BASE_URL, page); await browser.close(); } This is fairly boring glue code; the actual crawling is happening within sitemap.js: createSiteMap determines URLs and writes them to disk. readSiteMap merely reads any previously created site map from disk. This will be our foundation for dynamically generating tests. (We’ll see later why this needs to be synchronous.) Fortunately, the website in question provides a comprehensive index of all pages, so my crawler only needs to collect unique local URLs from that index page: function extractLocalLinks(baseURL) { let urls = new Set(); let offset = baseURL.length; for(let { href } of document.links) { if(href.startsWith(baseURL)) { let path = href.slice(offset); urls.add(path); } } return Array.from(urls); } Wrapping that in a more boring glue code gives us our sitemap.js: import { readFileSync, writeFileSync } from "node:fs"; import { join } from "node:path"; let ENTRY_POINT = "/topics"; let SITEMAP = join(__dirname, "./sitemap.json"); export async function createSiteMap(baseURL, page) { await page.goto(baseURL + ENTRY_POINT); let urls = await page.evaluate(extractLocalLinks, baseURL); let data = JSON.stringify(urls, null, 4); writeFileSync(SITEMAP, data, { encoding: "utf-8" }); } export function readSiteMap() { try { var data = readFileSync(SITEMAP, { encoding: "utf-8" }); } catch(err) { if(err.code === "ENOENT") { throw new Error("missing site map"); } throw err; } return JSON.parse(data); } function extractLocalLinks(baseURL) { // etc. } The interesting bit here is that extractLocalLinks is evaluated within the browser context — thus we can rely on DOM APIs, notably document.links — while the rest is executed within the Playwright environment (i.e. Node). Tests Now that we have our list of URLs, we basically just need a test file with a simple loop to dynamically generate corresponding tests: for(let url of readSiteMap()) { test(`page at ${url}`, async ({ page }) => { await page.goto(url); await expect(page).toHaveScreenshot(); }); } This is why readSiteMap had to be synchronous above: Playwright doesn’t currently support top-level await within test files. In practice, we’ll want better error reporting for when the site map doesn’t exist yet. Let’s call our actual test file viz.test.js: import { readSiteMap } from "./sitemap.js"; import { test, expect } from "@playwright/test"; let sitemap = []; try { sitemap = readSiteMap(); } catch(err) { test("site map", ({ page }) => { throw new Error("missing site map"); }); } for(let url of sitemap) { test(`page at ${url}`, async ({ page }) => { await page.goto(url); await expect(page).toHaveScreenshot(); }); } Getting here was a bit of a journey, but we’re pretty much done… unless we have to deal with reality, which typically takes a bit more tweaking. Exceptions Because visual testing is inherently flaky, we sometimes need to compensate via special casing. Playwright lets us inject custom CSS, which is often the easiest and most effective approach. Tweaking viz.test.js… // etc. import { join } from "node:path"; let OPTIONS = { stylePath: join(__dirname, "./viz.tweaks.css") }; // etc. await expect(page).toHaveScreenshot(OPTIONS); // etc. … allows us to define exceptions in viz.tweaks.css: /* suppress state */ main a:visited { color: var(--color-link); } /* suppress randomness */ iframe[src$="/articles/signals-reactivity/demo.html"] { visibility: hidden; } /* suppress flakiness */ body:has(h1 a[href="/wip/unicode-symbols/"]) { main tbody > tr:last-child > td:first-child { font-size: 0; visibility: hidden; } } :has() strikes again! Page vs. viewport At this point, everything seemed hunky-dory to me, until I realized that my tests didn’t actually fail after I had changed some styling. That’s not good! What I hadn’t taken into account is that .toHaveScreenshot only captures the viewport rather than the entire page. We can rectify that by further extending playwright.config.js. export let WIDTH = 800; export let HEIGHT = WIDTH; // etc. projects: BROWSERS.map(ua => ({ name: ua.toLowerCase().replaceAll(" ", "-"), use: { ...devices[ua], viewport: { width: WIDTH, height: HEIGHT } } })) …and then by adjusting viz.test.js‘s test-generating loop: import { WIDTH, HEIGHT } from "./playwright.config.js"; // etc. for(let url of sitemap) { test(`page at ${url}`, async ({ page }) => { checkSnapshot(url, page); }); } async function checkSnapshot(url, page) { // determine page height with default viewport await page.setViewportSize({ width: WIDTH, height: HEIGHT }); await page.goto(url); await page.waitForLoadState("networkidle"); let height = await page.evaluate(getFullHeight); // resize viewport for before snapshotting await page.setViewportSize({ width: WIDTH, height: Math.ceil(height) }); await page.waitForLoadState("networkidle"); await expect(page).toHaveScreenshot(OPTIONS); } function getFullHeight() { return document.documentElement.getBoundingClientRect().height; } Note that we’ve also introduced a waiting condition, holding until there’s no network traffic for a while in a crude attempt to account for stuff like lazy-loading images. Be aware that capturing the entire page is more resource-intensive and doesn’t always work reliably: You might have to deal with layout shifts or run into timeouts for long or asset-heavy pages. In other words: This risks exacerbating flakiness. Conclusion So much for that quick spike. While it took more effort than expected (I believe that’s called “software development”), this might actually solve my original problem now (not a common feature of software these days). Of course, shaving this yak still leaves me itchy, as I have yet to do the actual work of scratching CSS without breaking anything. Then comes the real challenge: Retrofitting dark mode to an existing website. I just might need more downtime. Automated Visual Regression Testing With Playwright originally published on CSS-Tricks, which is part of the DigitalOcean family. You should get the newsletter.

                                                                                                                                                                                                                                                                                                                                                                    Case Study: Combining Cutting-Edge CSS Features Into a “Course Navigation” Component

                                                                                                                                                                                                                                                                                                                                                                    • Articles
                                                                                                                                                                                                                                                                                                                                                                    • Case Studies

                                                                                                                                                                                                                                                                                                                                                                    Having been tasked with creating a UI component for navigating the content of an online course, Daniel found himself neck-deep in a pool of new CSS features that he wound up using on the project.

                                                                                                                                                                                                                                                                                                                                                                    Case Study: Combining Cutting-Edge CSS Features Into a “Course Navigation” Component originally published on CSS-Tricks, which is part of the DigitalOcean family. You should get the newsletter.

                                                                                                                                                                                                                                                                                                                                                                    I came across this awesome article navigator by Jhey Tompkins: CodePen Embed Fallback It solved a UX problem I was facing on a project, so I’ve adapted it to the needs of an online course — a “course navigator” if you will — and built upon it. And today I’m going to pick it apart and show you how it all works: CodePen Embed Fallback You can see I’m imagining this as some sort of navigation that you might find in an online learning management system that powers an online course. To summarize what this component does, it: links to all course lessons, smoothly scrolls to anchored lesson headings, indicates how much of the current lesson has been read, toggles between light and dark modes, and sits fixed at the bottom and collapses on scroll. Also, while not a feature, we won’t be using JavaScript. You might think that’s impossible, but the spate of CSS features that have recently shipped make all of this possible with vanilla CSS, albeit using bleeding-edge techniques that are only fully supported by Chrome at the time I’m writing this. So, crack open the latest version and let’s do this together! The HTML We’re looking at a disclosure widget (the <details> element) pinned to the bottom of the page with fixed positioning. Behind it? A course lesson (or something of that effect) wrapped in an <article> with ids on the headings for same-page anchoring. Clicking on the disclosure’s <summary> toggles the course navigation, which is wrapped in a ::details-content pseudo-element. This navigation links to other lessons but also scrolls to the aforementioned headings of the current lesson. The <summary> contains a label (since it functions as a toggle-disclosure button), the name of the current lesson, the distance scrolled, and a dark mode toggle. With me so far? <details> <!-- The toggle (flex →) --> <summary> <span><!-- Toggle label --></span> <span><!-- Current lesson + % read --></span> <label><!-- Light/dark-mode toggle --></label> </summary> <!-- ::details-content --> <!-- Course navigation --> <!-- /::details-content --> </details> <article> <h1 id="sectionA">Section A</h1> <p>...</p> <h2 id="sectionB">Section B</h2> <p>...</p> <h2 id="sectionC">Section C</h2> <p>...</p> </article> Getting into position First, we’ll place the disclosure with fixed positioning so that it’s pinned to the bottom of the page: details { position: fixed; inset: 24px; /* Use as margin */ place-self: end center; /* y x */ } Setting up CSS-only dark mode (the new way) There are certain scenarios where dark mode is better for accessibility, especially for the legibility of long-form content, so let’s set that up. First, the HTML. We have an ugly checkbox input that’s hidden thanks to its hidden attribute, followed by an <i> which’ll be a better-looking faux checkbox once we’ve sprinkled on some Font Awesome, followed by a <span> for the checkbox’s text label. All of this is then wrapped in an actual <label>, which is wrapped by the <summary>. We wrap the label’s content in a <span> so that flexbox gaps get applied between everything. Functionally, even though the checkbox is hidden, it toggles whenever its label is clicked. And on that note, it might be a good idea to place an explicit aria-label on this label, just to be 100% sure that screen readers announce a label, since implicit labels don’t always get picked up. <details> <summary> <!-- ... --> <label aria-label="Dark mode"> <input type="checkbox" hidden> <i></i> <span>Dark mode</span> </label> </summary> <!-- ... --> </details> Next we need to put the right icons in there, subject to a little conditional logic. Rather than use Font Awesome’s HTML classes and have to mess around with CSS overwrites, we’ll use Font Awesome’s CSS properties with our rule logic, as follows: If the <i> element is followed by (notice the next-sibling combinator) a checked checkbox, we’ll display a checked checkbox icon in it. If it’s followed by an unchecked checkbox, we’ll display an unchecked checkbox icon in it. It’s still the same rule logic even if you don’t use Font Awesome. /* Copied from Font Awesome’s CSS */ i::before { font-style: normal; font-family: "Font Awesome 6 Free"; display: inline-block; width: 1.25em; /* Prevents content shift when swapping to differently sized icons by making them all have the same width (this is equivalent to Font Awesome’s .fa-fw class) */ } /* If followed by a checked checkbox... */ input[type=checkbox]:checked + i::before { content: "\f058"; font-weight: 900; } /* If followed by an unchecked checkbox... */ input[type=checkbox]:not(:checked) + i::before { content: "\f111"; font-weight: 400; } We need to implement the modes at the root level (again, using a little conditional logic). If the root :has the checked checkbox, apply color-scheme: dark. If the root does :not(:has) the unchecked checkbox, then we apply color-scheme: light. /* If the root has a checked checkbox... */ :root:has(input[type=checkbox]:checked) { color-scheme: dark; } /* If the root does not have a checked checkbox... */ :root:not(:has(input[type=checkbox]:checked)) { color-scheme: light; } If you toggle the checkbox, your web browser’s UI will already toggle between light and dark color schemes. Now let’s make sure that our demo does the same thing using the light-dark() CSS function, which takes two values — the light mode color and then the dark mode color. You can utilize this function instead of any color data type (later on we’ll even use it within a conic gradient). In the demo I’m using the same HSL color throughout but with different lightness values, then flipping the lightness values based on the mode: color: light-dark(hsl(var(--hs) 90%), hsl(var(--hs) 10%)); background: light-dark(hsl(var(--hs) 10%), hsl(var(--hs) 90%)); I don’t think the light-dark() function is any better than swapping out CSS variables, but I don’t believe it’s any worse either. Totally up to you as far as which approach you choose. Displaying scroll progress Now let’s display the amount read as defined by the scroll progress, first, as what I like to call a “progress pie” and then, second, as a plain-text percentage. These’ll go in the middle part of the <summary>: <details> <summary> <!-- ... --> <span> <span id="progress-pie"></span> <span>1. LessonA</span> <span id="progress-percentage"></span> </span> <!-- ... --> </summary> <!-- ... --> </details> What we need is to display the percentage and allow it to “count” as the scroll position changes. Normally, this is squarely in JavaScript territory. But now that we can define our own custom properties, we can establish a variable called --percentage that is formatted as an integer that defaults to a value of 0. This provides CSS with the context it needs to read and interpolate the value between 0 and 100, which is the maximum value we want to support. So, first, we define the variable as a custom property: @property --percentage { syntax: "<integer>"; inherits: true; initial-value: 0; } Then we define the animation in keyframes so that the value of --percentage is updated from 0 to 100: @keyframes updatePercentage { to { --percentage: 100; } } And, finally, we apply the animation on the root element: :root { animation: updatePercentage; animation-timeline: scroll(); counter-reset: percentage var(--percentage); } Notice what we’re doing here: this is a scroll-driven animation! By setting the animation-timeline to scroll(), we’re no longer running the animation based on the document’s timeline but instead based on the user’s scroll position. You can dig deeper into scroll timelines in the CSS-Tricks Almanac. Since we’re dealing with an integer, we can target the ::before pseudo-element and place the percentage value inside of it using the content property and a little counter() hacking (followed by the percentage symbol): #progress-percentage::before { content: counter(percentage) "%"; min-width: 40px; display: inline-block; /* Prevents content shift */ } The progress pie is just as straightforward. It’s a conic gradient made up of two colors that are positioned using 0% and the scroll percentage! This means that you’ll need that --percentage variable as an actual percentage, but you can convert it into such by multiplying it by 1% (calc(var(--percentage) * 1%))! #progress-pie { aspect-ratio: 1; background: conic-gradient(hsl(var(--hs) 50%) calc(var(--percentage) * 1%), light-dark(hsl(var(--hs) 90%), hsl(var(--hs) 10%)) 0%); border-radius: 50%; /* Make it a circle */ width: 17px; /* Same dimensions as the icons */ } Creating a (good) course navigation Now for the table contents containing the nested lists of lesson sections within them, starting with some resets. While there are more resets in the demo and more lines of code overall, two specific resets are vital to the UX of this component. First, here’s an example of how the nested lists are marked up: <details> <summary> <!-- ... --> </summary> <ol> <li class="active"> <a>LessonA</a> <ol> <li><a href="#sectionA">SectionA</a></li> <li><a href="#sectionB">SectionB</a></li> <li><a href="#sectionC">SectionC</a></li> </ol> </li> <li><a>LessonB</a></li> <li><a>LessonC</a></li> </ol> </details> Let’s reset the list spacing in CSS: ol { padding-left: 0; list-style-position: inside; } padding-left: 0 ensures that the parent list and all nested lists snap to the left side of the disclosure, minus any padding you might want to add. Don’t worry about the indentation of nested lists — we have something planned for those. list-style-position: inside ensures that the list markers snap to the side, rather than the text, causing the markers to overflow. After that, we slap color: transparent on the ::markers of nested <li> elements since we don’t need the lesson section titles to be numbered. We’re only using nested lists for semantics, and nested numbered lists specifically because a different type of list marker (e.g., bullets) would cause vertical misalignment between the course’s lesson titles and the lesson section titles. ol ol li::marker { color: transparent; } Finally, so that users can more easily traverse the current lesson, we’ll dim all list items that aren’t related to the current lesson. It’s a form of emphasizing something by de-emphasizing others: details { /* The default color */ color: light-dark(hsl(var(--hs) 90%), hsl(var(--hs) 10%)); } /* <li>s without .active that’re direct descendants of the parent <ol> */ ol:has(ol) > li:not(.active) { /* A less intense color */ color: light-dark(hsl(var(--hs) 80%), hsl(var(--hs) 20%)); } /* Also */ a { color: inherit; } One more thing… those anchor links scroll users to specific headings, right? So, putting scroll-behavior: smooth on the root to enables smooth scrolling between them. And that percentage-read tracker that we created? Yep, that’ll work here as well. :root { scroll-behavior: smooth; /* Smooth anchor scrolling */ scroll-padding-top: 20px; /* A scroll offset, basically */ } Transitioning the disclosure Next, let’s transition the opening and closing of the ::details-content pseudo-element. By default, the <details> element snaps open and closed when clicked, but we want a smooth transition instead. Geoff recently detailed how to do this in a comprehensive set of notes about the <details> element, but we’ll break it down together. First, we’ll transition from height: 0 to height: auto. This is a brand-new feature in CSS! We start by “opting into” the feature at the root level with interpolate-size: allow-keywords`: :root { interpolate-size: allow-keywords; } I recommend setting overflow-y: clip on details::details-content to prevent the content from overflowing the disclosure as it transitions in and out: details::details-content { overflow-y: clip; } Another option is sliding the content out and then fading it in (and vice-versa), but you’ll need to be quite specific about the transition’s setup. First, for the “before” and “after” states, you’ll need to target both details[open] and details:not([open]), because vaguely targeting details and then overwriting the transitioning styles with details[open] doesn’t allow us to reverse the transition. After that, slap the same transition on both but with different values for the transition delays so that the fade happens after when opening but before when closing. Finally, you’ll also need to specify which properties are transitioned. We could simply put the all keyword in there, but that is neither performant nor allows us to set the transition durations and delays for each property. So we’ll list them individually instead in a comma-separated list. Notice that we’re specifically transitioning the content-visibility and using the allow-discrete keyword because it is a discrete property. this is why we opted into interpolate-size: allow-keywords earlier. details:not([open])::details-content { height: 0; opacity: 0; padding: 0 42px; filter: blur(10px); border-top: 0 solid light-dark(hsl(var(--hs) 30%), hsl(var(--hs) 70%)); transition: height 300ms 300ms, padding-top 300ms 300ms, padding-bottom 300ms 300ms, content-visibility 300ms 300ms allow-discrete, filter 300ms 0ms, opacity 300ms 0ms; } details[open]::details-content { height: auto; opacity: 1; padding: 42px; filter: blur(0); border-top: 1px solid light-dark(hsl(var(--hs) 30%), hsl(var(--hs) 70%)); transition: height 300ms 0ms, padding-top 300ms 0ms, padding-bottom 300ms 0ms, content-visibility 300ms 0ms allow-discrete, filter 300ms 300ms, opacity 300ms 300ms; } Giving the summary a label and icons Preceding the current lesson’s title, percentage read, and dark mode toggle, the <summary> element needs a label that helps describe what it does. I went with “Navigate course” and included an aria-label saying the same thing so that screen readers didn’t announce all that other stuff. <details> <summary aria-label="Navigate course"> <span> <i></i> <span>Navigate course</span> </span> <!-- ... --> </summary> <!-- ... --> </details> In addition, the summary gets display: flex so that we can easily separate the three sections with a gap, which also removes the summary’s default marker, allowing you to use your own. (Again, I’m using Font Awesome in the demo.) i::before { width: 1.25em; font-style: normal; display: inline-block; font-family: "Font Awesome 6 Free"; } details i::before { content: "\f0cb"; /* fa-list-ol */ } details[open] i::before { content: "\f00d"; /* fa-xmark */ } /* For older Safari */ summary::-webkit-details-marker { display: none; } And finally, if you’re pro-cursor: pointer for most interactive elements, you’ll want to use it on the summary and manually make sure that the checkbox’s label inherits it, as it doesn’t do that automatically. summary { cursor: pointer; } label { cursor: inherit; } Giving the disclosure an auto-closure mechanism A tiny bit of JavaScript couldn’t hurt though, could it? I know I said this is a no-JavaScript deal, but this one-liner will automatically close the disclosure when the mouse leaves it: document.querySelector("details").addEventListener("mouseleave", e => e.target.removeAttribute("open")); Annoying or useful? I’ll let you decide. Setting the preferred color scheme automatically Setting the preferred color scheme automatically is certainly useful, but if you like to avoid JavaScript wherever possible, I don’t think users will be too mad for not offering this feature. Either way, the following conditional snippet checks if the user’s preferred color scheme is “dark” by evaluating the relevant CSS media query (prefers-color-scheme: dark) using window.matchMedia and matches. If the condition is met, the checkbox gets checked, and then the CSS handles the rest. if (window.matchMedia("prefers-color-scheme: dark").matches) { document.querySelector("input[type=checkbox]").checked = true; } Recap This has been fun! It’s such a blessing we can combine all of these cutting-edge CSS features, not just into one project but into a single component. To summarize, that includes: a course navigator that shows the current lesson, all other lessons, and smooth scrolls between the different headings, a percentage-scrolled tracker that shows the amount read in plain text and as a conic gradient… pie chart, a light/dark-mode toggle (with some optional JavaScript that detects the preferred color scheme), and it is all packed into a single, floating, animated, native disclosure component. The newer CSS features we covered in the process: Scroll-driven animations interpolate-size: allow-keywords for transitioning between 0 and auto smooth scrolling by way of scroll-behavior: smooth dark mode magic using the light-dark() function a progress chart made with a conic-gradient() styling the ::details-content pseudo-element animating the <details> element Thanks to Jhey for the inspiration! If you’re not following Jhey on Bluesky or X, you’re missing out. You can also see his work on CodePen, some of which he has talked about right here on CSS-Tricks. Case Study: Combining Cutting-Edge CSS Features Into a “Course Navigation” Component originally published on CSS-Tricks, which is part of the DigitalOcean family. You should get the newsletter.

                                                                                                                                                                                                                                                                                                                                                                    Support Logical Shorthands in CSS

                                                                                                                                                                                                                                                                                                                                                                    • Links
                                                                                                                                                                                                                                                                                                                                                                    • at-rules
                                                                                                                                                                                                                                                                                                                                                                    • csswg
                                                                                                                                                                                                                                                                                                                                                                    • specifications

                                                                                                                                                                                                                                                                                                                                                                    There’s a bit of a blind spot when working with CSS logical properties concerning shorthands.

                                                                                                                                                                                                                                                                                                                                                                    Support Logical Shorthands in CSS originally published on CSS-Tricks, which is part of the DigitalOcean family. You should get the newsletter.

                                                                                                                                                                                                                                                                                                                                                                    There’s a bit of a blind spot when working with CSS logical properties concerning shorthands. Miriam explains: Logical properties are a great way to optimize our sites in advance, without any real effort. But what if we want to set multiple properties at once? This is where shorthands like margin and padding become useful. But they are currently limited to setting physical dimension. Logical properties are great, but they still feel like a second-class feature of the language. There are a few 2-value shorthands that have been implemented, like margin-block for setting both the -block-start and -block-endmargins. I find those extremely useful and concise. But the existing 4-value shorthands feel stuck in the past. It’s surprising that a size shorthand can’t set the inline-size, and the inset shorthand doesn’t include inset-block-start. Is there any way to update those shorthand properties so that they can be used to set logical dimensions? She ends with the money question, whether we can do anything about it. We’re currently in a position of having to choose between supporting flow-relative terms like block-start and inline-start with longhand properties and the ergonomic benefits of writing shorthand properties that are evaluated as physical terms like top, bottom, left, and right. Those of us writing CSS for a while likely have the muscle memory to adapt accordingly, but it’s otherwise a decision that has real consequences, particularly for multi-lingual sites. Note that Miriam says this is something the CSS Working Group has been working on since 2017. And there’s a little momentum to pick it up and do something about it. The first thing you can do is support Miriam’s work — everything she does with the CSS Working Group (and it’s a lot) is a labor of love and relies on sponsorships, so chipping in is one way to push things forward. The other thing you can do is chime into Miriam’s proposal that she published in 2021. I think it’s a solid idea. We can’t simply switch from physical to flow-relative terms in shorthand properties without triggering compatibility issues, so having some sort of higher-level instruction for CSS at the top of the stylesheet, perhaps as an at-rule that specifies which “mode” we’re in. <coordinate-mode> = [ logical | physical ] or [ relative | absolute ] or ... @mode <coordinate-mode>; /* must come after @import and before any style rules */ @mode <coordinate-mode> { <stylesheet> } selector { property: value !<coordinate-mode>; } Perhaps naming aside, it seems pretty reasonable, eh? Support Logical Shorthands in CSS originally published on CSS-Tricks, which is part of the DigitalOcean family. You should get the newsletter.

                                                                                                                                                                                                                                                                                                                                                                    Revisiting CSS border-image

                                                                                                                                                                                                                                                                                                                                                                    • Articles
                                                                                                                                                                                                                                                                                                                                                                    • border

                                                                                                                                                                                                                                                                                                                                                                    I’ve used border-image regularly. Yet, it remains one of the most underused CSS tools, and I can’t, for the life of me, figure out why. Is it possible that people steer clear of border-image because its syntax is awkward and unintuitive? Perhaps it’s because most explanations don’t solve the type of creative implementation problems that most people need to solve. Most likely, it’s both.

                                                                                                                                                                                                                                                                                                                                                                    Revisiting CSS border-image originally published on CSS-Tricks, which is part of the DigitalOcean family. You should get the newsletter.

                                                                                                                                                                                                                                                                                                                                                                    In my last article on “Revisiting CSS Multi-Column Layout”, I mentioned that almost twenty years have flown by since I wrote my first book, Transcending CSS. In it, I explained how and why to use what were, at the time, an emerging CSS property. Ten years later, I wrote the Hardboiled Web Design Fifth Anniversary Edition, covering similar ground and introducing the new CSS border-image property. Hint: I published an updated version, Transcending CSS Revisited which is free to read online. Hardboiled Web Design is available from my bookshop. I was very excited about the possibilities this new property would offer. After all, we could now add images to the borders of any element, even table cells and rows (unless their borders had been set to collapse). Since then, I’ve used border-image regularly. Yet, it remains one of the most underused CSS tools, and I can’t, for the life of me, figure out why. Is it possible that people steer clear of border-image because its syntax is awkward and unintuitive? Perhaps it’s because most explanations don’t solve the type of creative implementation problems that most people need to solve. Most likely, it’s both. I’ve recently been working on a new website for Emmy-award-winning game composer Mike Worth. He hired me to create a highly graphical design that showcases his work, and I used border-image throughout. Design by Andy Clarke, Stuff & Nonsense. Mike Worth’s website will launch in April 2025, but you can see examples from this article on CodePen. A brief overview of properties and values First, here’s a short refresher. Most border-image explanations begin with this highly illuminating code snippet: border-image: \[source\] [slice]/\[width]/[outset\] [repeat] This is shorthand for a set of border-image properties, but it’s best to deal with properties individually to grasp the concept more easily. A border-image’s source I’ll start with the source of the bitmap or vector format image or CSS gradient to be inserted into the border space: border-image-source: url('/img/scroll.png'); When I insert SVG images into a border, I have several choices as to how. I could use an external SVG file: border-image-source: url('/img/scroll.svg'); Or I might convert my SVG to data URI using a tool like Base64.Guru although, as both SVG and HTML are XML-based, this isn’t recommended: border-image-source: url('data:image/svg+xml;base64,…'); Instead, I can add the SVG code directly into the source URL value and save one unnecessary HTTP request: border-image-source: url('data:image/svg+xml;utf8,…'); Finally, I could insert an entirely CSS-generated conical, linear, or radial gradient into my border: border-image-source: conical-gradient(…); Tip: It’s useful to remember that a browser renders a border-image above an element’s background and box-shadow but below its content. More on that a little later. Slicing up a border-image Now that I’ve specified the source of a border image, I can apply it to a border by slicing it up and using the parts in different positions around an element. This can be the most baffling aspect for people new to border-image. Most border-image explanations show an example where the pieces will simply be equally-sized, like this: However, a border-image can be developed from any shape, no matter how complex or irregular. Instead of simply inserting an image into a border and watching it repeat around an element, invisible cut-lines slice up a border-image into nine parts. These lines are similar to the slice guides found in graphics applications. The pieces are, in turn, inserted into the nine regions of an element’s border. The border-image-slice property defines the size of each slice by specifying the distance from each edge of the image. I could use the same distance from every edge: border-image-slice: 65 I can combine top/bottom and left/right values: border-image-slice: 115 65; Or, I can specify distance values for all four cut-lines, running clockwise: top, right, bottom, left: border-image-slice: 65 65 115 125; The top-left of an image will be used on the top-left corner of an element’s border. The bottom-right will be used on the bottom-right, and so on. I don’t need to add units to border-image-slice values when using a bitmap image as the browser correctly assumes bitmaps use pixels. The SVG viewBox makes using them a little different, so I also prefer to specify their height and width: <svg height="600px" width="600px">…</svg> Don’t forget to set the widths of these borders, as without them, there will be nowhere for a border’s image to display: border-image-width: 65px 65px 115px 125px; Filling in the center So far, I’ve used all four corners and sides of my image, but what about the center? By default, the browser will ignore the center of an image after it’s been sliced. But I can put it to use by adding the fill keyword to my border-image-slice value: border-image-slice: 65px 65px 115px 125px fill; Setting up repeats With the corners of my border images in place, I can turn my attention to the edges between them. As you might imagine, the slice at the top of an image will be placed on the top edge. The same is true of the right, bottom, and left edges. In a flexible design, we never know how wide or tall these edges will be, so I can fine-tune how images will repeat or stretch when they fill an edge. Stretch: When a sliced image is flat or smooth, it can stretch to fill any height or width. Even a tiny 65px slice can stretch to hundreds or thousands of pixels without degrading. border-image-repeat: stretch; Repeat: If an image has texture, stretching it isn’t an option, so it can repeat to fill any height or width. border-image-repeat: repeat; Round: If an image has a pattern or shape that can’t be stretched and I need to match the edges of the repeat, I can specify that the repeat be round. A browser will resize the image so that only whole pieces display inside an edge. border-image-repeat: round; Space: Similar to round, when using the space property, only whole pieces will display inside an edge. But instead of resizing the image, a browser will add spaces into the repeat. border-image-repeat: space; When I need to specify a separate stretch, repeat, round, or space value for each edge, I can use multiple keywords: border-image-repeat: stretch round; Outsetting a border-image There can be times when I need an image to extend beyond an element’s border-box. Using the border-image-outset property, I can do just that. The simplest syntax extends the border image evenly on all sides by 10px: border-image-outset: 10px; Of course, there being four borders on every element, I could also specify each outset individually: border-image-outset: 20px 10px; /* or */ border-image-outset: 20px 10px 0; border-image in action Mike Worth is a video game composer who’s won an Emmy for his work. He loves ’90s animation — especially Disney’s Duck Tales — and he asked me to create custom artwork and develop a bold, retro-style design. My challenge when developing for Mike was implementing my highly graphical design without compromising performance, especially on mobile devices. While it’s normal in CSS to accomplish the same goal in several ways, here, border-image often proved to be the most efficient. Decorative buttons The easiest and most obvious place to start was creating buttons reminiscent of stone tablets with chipped and uneven edges. I created an SVG of the tablet shape and added it to my buttons using border-image: button { border-image-repeat: stretch; border-image-slice: 10 10 10 10 fill; border-image-source: url('data:image/svg+xml;utf8,…'); border-image-width: 20px; } I set the border-image-repeat on all edges to stretch and the center slice to fill so these stone tablet-style buttons expand along with their content to any height or width. CodePen Embed Fallback Article scroll I want every aspect of Mike’s website design to express his brand. That means continuing the ’90s cartoon theme in his long-form content by turning it into a paper scroll. The markup is straightforward with just a single article element: <article> <!-- ... --> </article> But, I struggled to decide how to implement the paper effect. My first thought was to divide my scroll into three separate SVG files (top, middle, and bottom) and use pseudo-elements to add the rolled up top and bottom parts of the scroll. I started by applying a vertically repeating graphic to the middle of my article: article { padding: 10rem 8rem; box-sizing: border-box; /* Scroll middle */ background-image: url('data:image/svg+xml;utf8,…'); background-position: center; background-repeat: repeat-y; background-size: contain; } Then, I added two pseudo-elements, each containing its own SVG content: article:before { display: block; position: relative; top: -30px; /* Scroll top */ content: url('data:image/svg+xml;utf8,…'); } article:after { display: block; position: relative; top: 50px; /* Scroll bottom */ content: url('data:image/svg+xml;utf8,…'); } While this implementation worked as expected, using two pseudo-elements and three separate SVG files felt clumsy. However, using border-image, one SVG, and no pseudo-elements feels more elegant and significantly reduces the amount of code needed to implement the effect. I started by creating an SVG of the complete tablet shape: And I worked out the position of the four cut-lines: Then, I inserted this single SVG into my article’s border by first selecting the source, slicing the image, and setting the top and bottom edges to stretch and the left and right edges to round: article { border-image-slice: 150 95 150 95 fill; border-image-width: 150px 95px 150px 95px; border-image-repeat: stretch round; border-image-source: url('data:image/svg+xml;utf8,…'); } The result is a flexible paper scroll effect which adapts to both the viewport width and any amount or type of content. CodePen Embed Fallback Home page overlay My final challenge was implementing the action-packed graphic I’d designed for Mike Worth’s home page. This contains a foreground SVG featuring Mike’s orangutan mascot and a zooming background graphic: <section> <!-- content --> <div>...</div> <!-- ape --> <div> <svg>…</svg> </div> </section> I defined the section as a positioning context for its children: section { position: relative; } Then, I absolutely positioned a pseudo-element and added the zooming graphic to its background: section:before { content: ""; position: absolute; z-index: -1; background-image: url('data:image/svg+xml;utf8,…'); background-position: center center; background-repeat: no-repeat; background-size: 100%; } I wanted this graphic to spin and add subtle movement to the panel, so I applied a simple CSS animation to the pseudo-element: @keyframes spin-bg { from { transform: rotate(0deg); } to { transform: rotate(360deg); } } section:before { animation: spin-bg 240s linear infinite; } Next, I added a CSS mask to fade the edges of the zooming graphic into the background. The CSS mask-image property specifies a mask layer image, which can be a PNG image, an SVG image or mask, or a CSS gradient: section:before { mask-image: radial-gradient(circle, rgb(0 0 0) 0%, rgb(0 0 0 / 0) 60%); mask-repeat: no-repeat; } At this point, you might wonder where a border image could be used in this design. To add more interactivity to the graphic, I wanted to reduce its opacity and change its color — by adding a colored gradient overlay — when someone interacts with it. One of the simplest, but rarely-used, methods for applying an overlay to an element is using border-image. First, I added a default opacity and added a brief transition: section:before { opacity: 1; transition: opacity .25s ease-in-out; } Then, on hover, I reduced the opacity to .5 and added a border-image: section:hover::before { opacity: .5; border-image: fill 0 linear-gradient(rgba(0,0,255,.25),rgba(255,0,0,1)); } You may ponder why I’ve not used the other border-image values I explained earlier, so I’ll dissect that declaration. First is the border-image-slice value, where zero pixels ensures that the eight corners and edges stay empty. The fill keyword ensures the middle section is filled with the linear gradient. Second, the border-image-source is a CSS linear gradient that blends blue into red. A browser renders this border-image above the background but behind the content. CodePen Embed Fallback Conclusion: You should take a fresh look at border-image The border-image property is a powerful, yet often overlooked, CSS tool that offers incredible flexibility. By slicing, repeating, and outsetting images, you can create intricate borders, decorative elements, and even dynamic overlays with minimal code. In my work for Mike Worth’s website, border-image proved invaluable, improving performance while maintaining a highly graphical aesthetic. Whether used for buttons, interactive overlays, or larger graphic elements, border-image can create visually striking designs without relying on extra markup or multiple assets. If you’ve yet to experiment with border-image, now’s the time to revisit its potential and add it to your design toolkit. Hint: Mike Worth’s website will launch in April 2025, but you can see examples from this article on CodePen. About Andy Clarke Often referred to as one of the pioneers of web design, Andy Clarke has been instrumental in pushing the boundaries of web design and is known for his creative and visually stunning designs. His work has inspired countless designers to explore the full potential of product and website design. Andy’s written several industry-leading books, including Transcending CSS, Hardboiled Web Design, and Art Direction for the Web. He’s also worked with businesses of all sizes and industries to achieve their goals through design. Visit Andy’s studio, Stuff & Nonsense, and check out his Contract Killer, the popular web design contract template trusted by thousands of web designers and developers. Revisiting CSS border-image originally published on CSS-Tricks, which is part of the DigitalOcean family. You should get the newsletter.

                                                                                                                                                                                                                                                                                                                                                                    Quick Reminder That :is() and :where() Are Basically the Same With One Key Difference

                                                                                                                                                                                                                                                                                                                                                                    • Articles
                                                                                                                                                                                                                                                                                                                                                                    • selectors
                                                                                                                                                                                                                                                                                                                                                                    • specificity

                                                                                                                                                                                                                                                                                                                                                                    I’ve seen a handful of recent posts talking about the utility of the :is() relational pseudo-selector. No need to delve into the details other than to say it can help make compound selectors a lot more readable.

                                                                                                                                                                                                                                                                                                                                                                    :is(section, article, aside, 

                                                                                                                                                                                                                                                                                                                                                                    Quick Reminder That :is() and :where() Are Basically the Same With One Key Difference originally published on CSS-Tricks, which is part of the DigitalOcean family. You should get the newsletter.

                                                                                                                                                                                                                                                                                                                                                                    I’ve seen a handful of recent posts talking about the utility of the :is() relational pseudo-selector. No need to delve into the details other than to say it can help make compound selectors a lot more readable. :is(section, article, aside, nav) :is(h1, h2, h3, h4, h5, h6) { color: #BADA55; } /* ... which would be the equivalent of: */ section h1, section h2, section h3, section h4, section h5, section h6, article h1, article h2, article h3, article h4, article h5, article h6, aside h1, aside h2, aside h3, aside h4, aside h5, aside h6, nav h1, nav h2, nav h3, nav h4, nav h5, nav h6 { color: #BADA55; } There’s just one catch: the specificity. The selector’s specificity matches the most specific selector in the function’s arguments. That’s not a big deal when working with a relatively flat style structure containing mostly element and class selectors, but if you toss an ID in there, then that’s the specificity you’re stuck with. /* Specificity: 0 0 1 */ :is(h1, h2, h3, h4, h5, h6) { color: #BADA55; } /* Specificity: 1 0 0 */ :is(h1, h2, h3, h4, h5, h6, #id) { color: #BADA55; } That can be a neat thing! For example, you might want to intentionally toss a made-up ID in there to force a style the same way you might do with the !important keyword. What if you don’t want that? Some articles suggest nesting selectors instead which is cool but not quite with the same nice writing ergonomics. There’s where I want to point to the :where() selector instead! It’s the exact same thing as :is() but without the specificity baggage. It always carries a specificity score of zero. You might even think of it as a sort of specificity reset. /* Specificity: 0 0 0 */ :where(h1, h2, h3, h4, h5, h6) { color: #BADA55; } /* Specificity: 0 0 0 */ :where(h1, h2, h3, h4, h5, h6, #id) { color: #BADA55; } So, is there a certain selector hijacking your :is() specificity? You might want :where() instead. Quick Reminder That :is() and :where() Are Basically the Same With One Key Difference originally published on CSS-Tricks, which is part of the DigitalOcean family. You should get the newsletter.

                                                                                                                                                                                                                                                                                                                                                                    Styling Counters in CSS

                                                                                                                                                                                                                                                                                                                                                                    • Guides
                                                                                                                                                                                                                                                                                                                                                                    • counters
                                                                                                                                                                                                                                                                                                                                                                    • lists

                                                                                                                                                                                                                                                                                                                                                                    Going from the most basic ways to style lists directly in HTML to advanced customization techniques that are even capable of making things that aren't lists look like lists.

                                                                                                                                                                                                                                                                                                                                                                    Styling Counters in CSS originally published on CSS-Tricks, which is part of the DigitalOcean family. You should get the newsletter.

                                                                                                                                                                                                                                                                                                                                                                    Yes, you are reading that correctly: This is indeed a guide to styling counters with CSS. Some of you are cheering, “Finally!”, but I understand that the vast majority of you are thinking, “Um, it’s just styling lists.” If you are part of the second group, I get it. Before learning and writing more and more about counters, I thought the same thing. Now I am part of the first group, and by the end of this guide, I hope you join me there. There are many ways to create and style counters, which is why I wanted to write this guide and also how I plan to organize it: going from the most basic styling to the top-notch level of customization, sprinkling in between some sections about spacing and accessibility. It isn’t necessary to read the guide in order — each section should stand by itself, so feel free to jump to any part and start reading. Table of Contents HTML Based Customization Styling Simple Counters in CSS Custom Counters Custom Counters Styles Images in Counters Spacing Things out Accessibility Almanac references Further reading Customizing Counters in HTML Lists elements were among the first 18 tags that made up HTML. Their representation wasn’t defined yet but deemed fitting a bulleted list for unordered lists, and a sequence of numbered paragraphs for an ordered list. Cool but not enough; soon people needed more from HTML alone and new list attributes were added throughout the years to fill in the gaps. start The start attribute takes an integer and sets from where the list should start: <ol start="2"> <li>Bread</li> <li>Milk</li> <li>Butter</li> <li>Apples</li> </ol> Bread Milk Butter Apples Although, it isn’t limited to positive values; zero and negative integers are allowed as well: <ol start="0"> <li>Bread</li> <li>Milk</li> <li>Butter</li> <li>Apples</li> </ol> <ol start="-2"> <li>Bread</li> <li>Milk</li> <li>Butter</li> <li>Apples</li> </ol> Bread Milk Butter Apples Bread Milk Butter Apples type We can use the type attribute to change the counter’s representation. It’s similar to CSS’s list-style-type, but it has its own limited uses and shouldn’t be used interchangeably*. Its possible values are: 1 for decimal numbers (default) a for lowercase alphabetic A for uppercase alphabetic i for lowercase Roman numbers I for uppercase Roman numbers <ol type="a"> <li>Bread</li> <li>Milk</li> <li>Butter</li> <li>Apples</li> </ol> <ol type="i"> <li>Bread</li> <li>Milk</li> <li>Butter</li> <li>Apples</li> </ol> Bread Milk Butter Apples Bread Milk Butter Apples It’s weird enough to use type on ol elements, but it still has some use cases*. However, usage with the ul element is downright deprecated. value The value attribute sets the value for a specific li element. This also affects the values of the li elements after it. <ol> <li>Bread</li> <li value="4">Milk</li> <li>Butter</li> <li>Apples</li> </ol> Bread Milk Butter Apples reversed The reversed attribute will start counting elements in reverse order, so from highest to lowest. <ol reversed> <li>Bread</li> <li>Milk</li> <li>Butter</li> <li>Apples</li> </ol> Bread Milk Butter Apples All can be combined If you ever feel the need, all list attributes can be combined in one (ordered) list. <ol reversed start="2" type="i"> <li>Bread</li> <li value="4">Milk</li> <li>Butter</li> <li>Apples</li> </ol> Bread Milk Butter Apples * Do we need them if we now have CSS? Funny enough, the first CSS specification already included list-style-type and other properties to style lists, and it was released before HTML 3.2 — the first HTML spec that included some of the previous list attributes. This means that at least on paper, we had CSS list styling before HTML list attributes, so the answer isn’t as simple as “they were there before CSS.” Without CSS, a static page (such as this guide) won’t be pretty, but at the very least, it should be readable. For example, the type attribute ensures that styled ordered lists won’t lose their meaning if CSS is missing, which is especially useful in legal or technical documents. Some attributes wouldn’t have a CSS equivalent until years later, including reversed, start and value. Styling Simple Counters in CSS For most use cases, styling lists in CSS doesn’t take more than a couple of rules, but even in that brevity, we can find different ways to style the same list. ::marker or ::before? The ::marker pseudo-element represents the counter part of a list item. As a pseudo-element, we can set its content property to any string to change its counter representation: li::marker { content: "💜 "; } Bread Milk Butter Apples The content in pseudo-elements also accepts images, which allows us to create custom markers: li::marker { content: url("./logo.svg") " "; } bread milk butter apples By default, only li elements have a ::marker but we can give it to any element by setting its display property to list-item: h4 { display: list-item; } h4::marker { content: "◦ "; } This will give each h4 a ::marker which we can change to any string: List Title However, ::marker is an odd case: it was described in the CSS spec more than 20 years ago, but only gained somewhat reliable support in 2020 and still isn’t fully supported in Safari. What’s worst, only font-related properties (such as font-size or color) are allowed, so we can’t change its margin or background-color. This has led many to use ::before instead of ::marker, so you’ll see a lot of CSS in which the author got rid of the ::marker using list-style-type: none and used ::before instead: li { /* removes ::marker */ list-style-type: none; } li::before { /* mimics ::marker */ content: "▸ "; } list-style-type The list-style-type property can be used to replace the ::marker‘s string. Unlike ::marker, list-style-type has been around forever and is most people’s go-to option for styling lists. It can take a lot of different counter styles that are built-in in browsers, but you will probably use one of the following: For unordered lists: disc circle square ul { list-style-type: square; } ul { list-style-type: circle; } bread milk butter apples For ordered lists: decimal decimal-leading-zero lower-roman upper-roman lower-alpha upper-alpha ol { list-style-type: upper-roman; } ol { list-style-type: lower-alpha; } bread milk butter apples You can find a full list of valid counter styles here. It can also take none to remove the marker altogether, and since not long ago, it can also take a <string> for ul elements. ul { list-style-type: none; } ul { list-style-type: "➡️ "; } Creating Custom Counters For a long time, there wasn’t a CSS-equivalent to the HTML reverse, start or value attributes. So if we wanted to reverse or change the start of multiple lists, instead of a CSS class to rule them all, we had to change their HTML one by one. You can imagine how repetitive that would get. Besides, list attributes simply had their limitations: we can’t change how they increment with each item and there isn’t an easy way to attach a prefix or suffix to the counter. And maybe the biggest reason of all is that there wasn’t a way to number things that weren’t lists! Custom counters let us number any collection of elements with a whole new level of customization. The workflow is to: Initiate the counter with the counter-reset property. Increment the counter with the counter-increment property. Individually set the counters with the counter-set property. Output the counters with either the counter() and counters() functions. As I mentioned, we can make a list out of any collection of elements, and while this has its accessibility concerns, just for demonstration’s sake, let’s try to turn a collection of headings like this… <div class="index"> <h2>The Old Buccaneer</h2> <h2>The Sea Cook</h2> <h2>My Shore Adventure</h2> <h2>The Log Cabin</h2> <h2>My Sea Adventure</h2> <h2>Captain Silver</h2> </div> …into something that looks list-like. But just because we can make an element look like a list doesn’t always mean we should do it. Be sure to consider how the list will be announced by assistive technologies, like screen readers, and see the Accessibility section for more information. Initiate counters: counter-reset The counter-reset property takes two things: the name of the counter as a custom ident and the initial count as an integer. If the initial count isn’t given, then it will start at 0 by default: .index { counter-reset: index; /* The same as */ counter-reset: index 0; } You can initiate several counters at once with a space-separated list and set a specific value for each one: .index { counter-reset: index another-counter 2; } This will start our index counter at 0 (the default) and another-counter at 2. Set counters: counter-set The counter-set works similar to counter-reset: it takes the counter’s name followed by an integer, but this time it will set the count for that element onwards. If the integer is omitted, it will set the counter to 0 by default. h2:nth-child(2) { counter-set: index; /* same as */ counter-set: index 0; } And we can set several counters at once, as well: h2:nth-child(3) { counter-set: index 5 another-counter 10; } This will set the third h2 element’s index count to 5 and another-counter to 10. If there isn’t an active counter with that name, counter-set will initiate it at 0. Increment counters: counter-increment Right now, we have our counter, but it will stagnate at 0 since we haven’t set which elements should increment it. We can use the counter-increment property for that, which takes the name of the counter and how much it should be incremented by. If we only write the counter’s name, it will increment it by 1. In this case, we want each h2 title to increment the counter by one, and that should be as easy as setting counter-increment to the counter’s name: h2 { counter-increment: index; /* same as */ counter-increment: index 1; } Just like with counter-reset, we can increment several counters at once in a space-separated list: h2 { counter-increment: index another-counter 2; } This will increment index by one and another-counter by two on each h2 element. If there isn’t an active counter with that name, counter-increment will initiate it at 0. Output simple lists: counter() So far, we won’t see any change in the counter representation. The counters are counting but not showing, so to output the counter’s result we use the counter() and counters() functions. Yes, those are two functions with similar names but important differences. The counter() function takes the name of a counter and outputs its content as a string. If many active counters have the same name, it will select the one that is defined closest to the element, so we can only output one counter at a time. As mentioned earlier, we can set an element’s display to list-item to work with its ::marker pseudo-element: h2 { display: list-item; } Then, we can use counter() in its content property to output the current count. This allows us to prefix and suffix the counter by writing a string before or after the counter() function: h2::marker { content: "Part " counter(index) ": "; } Alternatively, we can use the everyday ::before pseudo-element to the same effect: h2::before { content: "Part " counter(index) ": "; } Output nested lists: counters() counter() works great for most situations, but what if we wanted to do a nested list like this: 1. Paradise Beaches 1.1. Hawaiian Islands 1.2. Caribbean Getaway 1.2.1. Aruba 1.2.2. Barbados 2. Outdoor Escapades 2.1 National Park Hike 2.2. Mountain Skiing Trip We would need to initiate individual counters and write different counter() functions for each level of nesting, and that’s only possible if we know how deep the nesting goes, which we simply don’t at times. In this case, we use the counters() function, which also takes the name of a counter as an argument but instead of just outputting its content, it will join all active counters with that name into a single string and output it. To do so, it takes a string as a second argument, usually something like a dot (".") or dash ("-") that will be used between counters to join them. We can use counter-reset and counter-increment to initiate a counter for each ol element, while each li will increment its closest counter by 1: ol { counter-reset: item; } li { counter-increment: item; } But this time, instead of using counter() (which would only display one counter per item), we will use counters() to join all active counters by a string (e.g. ".“) and output them at once: li::marker { content: counters(item, ".") ". "; } Styling Counters Both the counter() and counters() functions accept one additional, yet optional, last argument representing the counter style, the same ones we use in the list-style-type property. So in our last two examples, we could change the counter styles to Roman numbers and alphabetic letters, respectively: h2::marker { content: "Part " counter(index, upper-roman) ": "; } li::marker { content: counters(item, ".", lower-alpha) ". "; } Reverse Counters It’s possible to count backward using custom counters, but we need to know beforehand the number of elements we’ll count. So for example, if we want to make a Top Five list in reversed order: <h1>Best rated animation movies</h1> <ol> <li>Toy Story 2</li> <li>Toy Story 1</li> <li>Finding Nemo</li> <li>How to Train your Dragon</li> <li>Inside Out</li> </ol> We have to initiate our counter at the total number of elements plus one (so it doesn’t end at 0): ol { counter-reset: movies 6; } And then set the increment to a negative integer: li { counter-increment: movies -1; } To output the count we use counter() as we did before: li::marker { content: counter(movies) ". "; } There is also a way to write reversed counters supported in Firefox, but it hasn’t shipped to any other browser. Using the reversed() functional notation, we can wrap the counter name while initiating it to say it should be reversed. ol { counter-reset: reversed(movies); } li { counter-increment: movies; } li::marker { content: counter(movies) " ."; } Styling Custom Counters The last section was all about custom counters: we changed from where they started and how they increased, but at the end of the day, their output was styled in one of the browser’s built-in counter styles, usually decimal. Now using @counter-style, we’ll build our own counter styles to style any list. The @counter-style at-rule, as its name implies, lets you create custom counter styles. After writing the at-rule it takes a custom ident as a name: @counter-style my-counter-style { /* etc. */ } That name can be used inside the properties and functions that take a counter style, such as list-style-type or the last argument in counter() and counters(): ul { list-style-type: my-counter-style; } li::marker { content: counter(my-counter, my-counter-style) ". "; } What do we write inside @counter-style? Descriptors! How many descriptors? Honestly, a lot. Just look at this quick review of all of them: system: specifies which algorithm will be used to construct the counter’s string representation. (Obligatory) negative: specifies the counter representation if the counter value is negative. (Optional) prefix: specifies a character that will be attached before the marker representation and any negative sign. (Optional) suffix: specifies a character that will be attached after the marker representation and any negative sign. (Optional) range: specifies the range in which the custom counter is used. Counter values outside the range will drop to their fallback counter style. (Optional) pad: specifies a minimum width all representations have to reach. Representations shorter than the minimum are padded with a character. (Optional) fallback: specifies a fallback counter used whenever a counter style can’t represent a counter value. (Optional) symbols: specifies the symbols used by the construction system algorithm. It’s obligatory unless the system is set to additive or extends. additive-symbols: specifies the symbols used by the construction algorithm when the system descriptor is set to additive. speak-as: specifies how screen readers should read the counter style. (Optional) However, I’ll focus on the required descriptors first: system, symbols and additive-symbols. The system descriptor The symbols or additive-symbols descriptors define the characters used for the counter style, while system says how to use them. The valid system values are: cyclic alphabetic symbolic additive fixed extends cyclic will go through the characters set on symbols and repeat them. We can use just one character in the symbols to mimic a bullet list: @counter-style cyclic-example { system: cyclic; symbols: "⏵"; suffix: " "; } bread butter milk apples Or alternate between two or more characters: @counter-style cyclic-example { system: cyclic; symbols: "🔸" "🔹"; suffix: " "; } fixed will write the characters in symbols descriptor just one time. In the last example, only the first two items will have a custom counter if set to fixed, while the others will drop to their fallback, which is decimal by default. @counter-style multiple-example { system: fixed; symbols: "🔸" "🔹"; suffix: " "; } We can set when the custom counters start by appending an <integer> to the fixed value. For example, the following custom counter will start at the fourth item: @counter-style fixed-example { system: fixed 4; symbols: "💠"; suffix: " "; } numeric will numerate list items using a custom positional system (base-2, base-8, base-16, etc.). Positional systems start at 0, so the first character at symbols will be used as 0, the next as 1, and so on. Knowing this, we can make an ordered list using non-decimal numerical systems like hexadecimal: @counter-style numeric-example { system: numeric; symbols: "0" "1" "2" "3" "4" "5" "6" "7" "8" "9" "A" "B" "C" "D" "E" "F"; suffix: ". "; } bread butter milk apples alphabetic will enumerate the list items using a custom alphabetical system. It’s similar to the numeric system but with the key difference that it doesn’t have a character for 0, so the next digits are just repeated. For example, if our symbols are "A" "B" "C" they will wrap to "AA", "AB", "AC", then BA, BB, BC and so on. Since there is no equivalent for 0 and negative values, they will drop down to their fallback. @counter-style alphabetic-example { system: alphabetic; symbols: "A" "B" "C"; suffix: ". "; } bread butter milk apples cinnamon symbolic will go through the characters in symbols repeating them one more time each iteration. So for example, if our symbols are "A", "B", "C", it will go “A”, “B”, and “C”, double them in the next iteration as “AA”, “BB”, and “CC”, then triple them as “AAA”, “BBB”, “CCC” and so on. Since there is no equivalent for 0 and negative values, they will drop down to their fallback. @counter-style symbolic-example { system: symbolic; symbols: "A" "B" "C"; suffix: ". "; } bread butter milk apples cinnamon additive will give characters a numerical value and add them together to get the counter representation. You can think of it as the way we usually count bills: if we have only $5, $2, and $1 bills, we will add them together to get the desired quantity, trying to keep the number of bills used at a minimum. So to represent 10, we will use two $5 bills instead of ten $1 bills. Since there is no equivalent for negative values, they will drop down to their fallback. @counter-style additive -example { system: additive; additive-symbols: 5 "5️⃣", 2 "2️⃣", 1 "1️⃣"; suffix: " "; } Notice how we use additive-symbols when the system is additive, while we use just symbols for the previous systems. extends will create a custom style from another one but with modifications. To do so, it takes a <counter-style-name> after the extends value. For example, we could change the decimal counter style default’s suffix to a closing parenthesis (")")`: @counter-style extends-example { system: extends decimal; suffix: ") "; } bread butter milk cinnamon Per spec, “If a @counter-style uses the extends system, it must not contain a symbols or additive-symbols descriptor, or else the @counter-style rule is invalid.” The other descriptors The negative descriptor allows us to create a custom representation for a list’s negative values. It can take one or two characters: The first one is prepended to the counter, and by default it’s the hyphen-minus ("-"). The second one is appended to the symbol. For example, we could enclose negative representations into parenthesis (2), (1), 0, 1, 2: @counter-style negative-example { system: extends decimal; negative: "(" ")"; } bread butter milk apples The prefix and suffix descriptors allow us to prepend and append, respectively, a character to the counter representation. We can use it to add a character at the beginning of each counter using prefix: @counter-style prefix-suffix-example { system: extends decimal; prefix: "("; suffix: ") "; } bread butter milk apples The range descriptor defines an inclusive range in which the counter style is used. We can define a bounded range by writing one <integer> next to another. For example, a range of 2 4 will affect elements 2, 3, and 4: @counter-style range-example { system: cyclic; symbols: "‣"; suffix: " "; range: 2 4; } bread butter milk apples cinnamon On the other hand, using the infinite value we can unbound the range to one side. For example, we could write infinite 3 so all items up to 3 have a counter style: @counter-style range-example { system: alphabetic; symbols: "A" "B" "C"; suffix: ". "; range: infinite 3; } bread butter milk apples cinnamon The pad descriptor takes an <integer> that represents the minimum width for the counter and a character to pad it. For example, a zero-padded counter style would look like the following: @counter-style pad-example { system: extends decimal; pad: 3 "0"; } bread butter milk apples The fallback descriptor allows you to define which counter style should be used as a fallback whenever we can’t represent a specific count. For example, the following counter style is fixed and will fallback to lower-roman after the sixth item: @counter-style fallback-example { system: fixed; symbols: "⚀" "⚁" "⚂" "⚃"; fallback: lower-roman; } bread butter milk apples cinnamon Lastly, the speak-as descriptor hints to speech readers on how the counter style should be read. It can be: auto Uses the system default. bullets reads an unordered list. By default, cyclic systems are read as bullets numbers reads the counter’s numeric value in the content language. By default, additive, fixed, numeric, and, symbolic are read as numbers. words reads the counter representation as words. spell-out reads the counter representation letter by letter. By default, alphabetic is read as spell-out. <counter-style-name> It will use that counter’s speak-as value. @counter-style speak-as-example { system: extends decimal; prefix: "Item "; suffix: " is "; speak-as: words; } symbols() The symbols() function defines an only-use counter style without the need to do a whole @counter-style, but at the cost of missing some features. It can be used inside the list-style-type property and the counter() and counters() functions. ol { list-style-type: symbols(cyclic "🥬"); } However, its browser support is appalling since it’s only supported in Firefox. Images in Counters In theory, there are four ways to add images to lists: list-style-image property content property symbols descriptor in @counter-style symbols() function. In practice, the only supported ways are using list-style-image and content, since support for images in @counter-style and support in general for symbols() isn’t the best (it’s pretty bad). list-style-image The list-style-image can take an image or a gradient. In this case, we want to focus on images but gradients can also be used to create custom square bullets: li { list-style-image: conic-gradient(red, yellow, lime, aqua, blue, magenta, red); } bread butter milk apples Sadly, changing the shape would require styling more the ::marker and this isn’t currently possible. To use an image, we pass its url(), make sure is small enough to work as a counter: li { list-style-image: url("./logo.svg"); } bread milk butter apples content The content property works similar to list-style-image: we pass the image’s url() and provide a little padding on the left as an empty string: li::marker { content: url("./logo.svg") " "; } Spacing Things Out You may notice in the last part how the image — depending on its size — isn’t completely centered on the text, and also that we provide an empty string on content properties for spacing instead of giving things either a padding or margin. Well, there’s an explanation for all of this, as since spacing is one of the biggest pain points when it comes to styling lists. Margins and paddings are wacky Spacing the ::marker from the list item should be as easy as increasing the marker’s or list margin, but in reality, it takes a lot more work. First, the padding and margin properties aren’t allowed in ::marker. While lists have two types of elements: the list wrapper (usually ol or ul) and the list item (li), each with a default padding and margin. Which should we use? You can test each property in this demo by Šime Vidas in his article dedicated to the gap after the list marker: CodePen Embed Fallback You’ll notice how the only property that affects the spacing within ::marker and the text is the li item’s padding property, while the rest of the spacing properties will move the entire list item. Another thing to note is even when the padding is set to 0px, there is a space after the ::marker. This is set by browsers and will vary depending on which browser you’re using. list-style-position One last thing you may notice in the demo is a checkbox for the list-style-position property, and how once you set it to inside, the ::marker will move to the inside of the box, at the cost of removing any spacing given by the list item’s padding. By default, markers are rendered outside the ul element’s box. A lot of times, this isn’t the best behavior: markers sneak out of elements, text-align won’t align the marker, and paradoxically, centered lists with flex or grid won’t look completely centered since the markers are outside the box. To change this we can use the list-style-position property, it can be either outside (default) and inside to define where to position the list marker: either outside or the outside of the ul box. ul { border: solid 2px red; } .inside { list-style-position: inside; } .outside { list-style-position: outside; } bread butter milk apple content with empty strings In the same article, Šime says: Appending a space to content feels more like a workaround than the optimal solution. And I completely agree that’s true, but just using ::marker there isn’t a correct way to add spacing between the ::marker and the list text, especially since most people prefer to set list-style-position to inside. So, as much as it pains me to say it, the simplest way to increase the gap after the marker is to suffix the content property with an empty string: li::marker { content: "• "; } bread milk butter apples BUT! This is only if we want to be purists and stick with the ::marker pseudo-element because, in reality, there is a much better way to position that marker: not using it at all. Just use ::before There is a reason people love using the ::before more than ::marker. First, we can’t use something like CSS Grid or Flexbox since changing the display of li to something other than list-item will remove the ::marker, and we can set the ::marker‘s height or width properties to better align it. Let’s be real, ::marker works fine when we just want simple styling. But we are not here for simple styling! Once we want something more involved, ::marker will fall short and we’ll have to use the ::before pseudo-element. Using ::before means we can use Flexbox, which allows for two things we couldn’t do before: Vertically center the marker with the text Easily increase the gap after the marker Both can be achieved with Flexbox: li { display: flex; align-items: center; /* Vertically center the marker */ gap: 20px; /* Increases the gap */ list-style-type: none; } The original ::marker is removed by changing the display. Accesibility In a previous section we turned things that weren’t lists into seemingly looking lists, so the question arises: should we actually do that? Doesn’t it hurt accessibility to make something look like a list when it isn’t one? As always, it depends. For a visual user, all the examples in this entry look all right, but for assistive technology users, some examples lack the necessary markup for accessible navigation. Take for example our initial demo. Here, listing titles serves as decoration since the markup structure is given by the titles themselves. It’s the same deal for the counting siblings demo from earlier, as assistive technology users can read the document through the title structure. However, this is the exception rather than the norm. That means a couple of the examples we looked at would fail if we need the list to be announced as a list in assistive technology, like screen readers. For example this list we looked at earlier: <div class="index"> <h2>The Old Buccaneer</h2> <h2>The Sea Cook</h2> <h2>My Shore Adventure</h2> <h2>The Log Cabin</h2> <h2>My Sea Adventure</h2> <h2>Captain Silver</h2> </div> …should be written as a list instead: <ul class="index"> <li>The Old Buccaneer</li> <li>The Sea Cook</li> <li>My Shore Adventure</li> <li>The Log Cabin</li> <li>My Sea Adventure</li> <li>Captain Silver</li> </ul> Listing elements is rarely used just as decoration, so as a rule of thumb, use lists in the markup even if you are planning to change them with CSS. Almanac References List Properties Almanac on Apr 23, 2021 list-style ul { list-style: square outside none; } counters lists Sara Cope Counters Almanac on Feb 4, 2025 counter-reset article { counter-reset: section; } counters lists Sara Cope Almanac on Jan 14, 2025 counter-increment .step { counter-increment: my-awesome-counter; } counters lists Sara Cope Almanac on Apr 23, 2021 counter-set h2:first-of-type::before { counter-set: chapter; } counters lists Geoff Graham Almanac on Feb 4, 2025 counter() h2::before { content: counter(my-counter, upper-roman) ". "; } counters lists Juan Diego Rodríguez Almanac on Feb 4, 2025 counters() li::marker { content: counters(item, ".") ") "; } counters lists Juan Diego Rodríguez Custom Counter Styles Almanac on Jan 28, 2025 @counter-style @counter-style apple-counter { ... } counters lists Juan Diego Rodríguez Almanac on Jan 30, 2025 symbols() ul { list-style: symbols(cyclic "🥬"); } counters lists Juan Diego Rodríguez Pseudo-Elements Almanac on Jan 19, 2025 ::marker li::marker { color: red; } counters lists Geoff Graham Almanac on Sep 13, 2024 ::before / ::after .element::before { content: "Yo!"; } counters lists Sara Cope More Tutorials & Tricks! Article on May 5, 2020 List Style Recipes counters lists Chris Coyier Article on Apr 29, 2021 List Markers and String Styles counters lists Eric Meyer Article on May 19, 2018 Style List Markers in CSS counters lists Chris Coyier Article on Jun 11, 2020 How to Reverse CSS Custom Counters counters lists Etinosa Obaseki Article on Jan 23, 2025 Some Things You Might Not Know About Custom Counter Styles counters lists Geoff Graham Article on Jan 26, 2022 Using CSS Counters for Custom List Number Styling counters lists Chris Coyier Article on May 17, 2024 Everything You Need to Know About the Gap After the List Marker counters lists Šime Vidas Styling Counters in CSS originally published on CSS-Tricks, which is part of the DigitalOcean family. You should get the newsletter.

                                                                                                                                                                                                                                                                                                                                                                    Web Components Demystified

                                                                                                                                                                                                                                                                                                                                                                    • Notes
                                                                                                                                                                                                                                                                                                                                                                    • web components

                                                                                                                                                                                                                                                                                                                                                                    Scott Jehl released a course called Web Components Demystified. This is my full set of notes from Scott's course. You'll still want to take the course on your own, and I encourage you to because Scott is an excellent teacher who makes all of this stuff extremely accessible, even to noobs like me.

                                                                                                                                                                                                                                                                                                                                                                    Web Components Demystified originally published on CSS-Tricks, which is part of the DigitalOcean family. You should get the newsletter.

                                                                                                                                                                                                                                                                                                                                                                    Scott Jehl released a course called Web Components Demystified. I love that name because it says what the course is about right on the tin: you’re going to learn about web components and clear up any confusion you may already have about them. And there’s plenty of confusion to go around! “Components” is already a loaded term that’s come to mean everything from a piece of UI, like a search component, to an element you can drop in and reuse anywhere, such as a React component. The web is chock-full of components, tell you what. But what we’re talking about here is a set of standards where HTML, CSS, and JavaScript rally together so that we can create custom elements that behave exactly how we want them to. It’s how we can make an element called <tasty-pizza> and the browser knows what to do with it. This is my full set of notes from Scott’s course. I wouldn’t say they’re complete or even a direct one-to-one replacement for watching the course. You’ll still want to do that on your own, and I encourage you to because Scott is an excellent teacher who makes all of this stuff extremely accessible, even to noobs like me. Chapter 1: What Web Components Are… and Aren’t Web components are not built-in elements, even though that’s what they might look like at first glance. Rather, they are a set of technologies that allow us to instruct what the element is and how it behaves. Think of it the same way that “responsive web design” is not a thing but rather a set of strategies for adapting design to different web contexts. So, just as responsive web design is a set of ingredients — including media fluid grids, flexible images, and media queries — web components are a concoction involving: Custom elements These are HTML elements that are not built into the browser. We make them up. They include a letter and a dash. <my-fancy-heading> Hey, I'm Fancy </my-fancy-heading> We’ll go over these in greater detail in the next module. HTML templates Templates are bits of reusable markup that generate more markup. We can hide something until we make use of it. <template> <li class="user"> <h2 class="name"></h2> <p class="bio"></p> </li> </template> Much more on this in the third module. Shadow DOM The DOM is queryable. document.querySelector("h1"); // <h1>Hello, World</h1> The Shadow DOM is a fragment of the DOM where markup, scripts, and styles are encapsulated from other DOM elements. We’ll cover this in the fourth module, including how to <slot> content. There used to be a fourth “ingredient” called HTML Imports, but those have been nixed. In short, web components might be called “components” but they aren’t really components more than technologies. In React, components sort of work like partials. It defines a snippet of HTML that you drop into your code and it outputs in the DOM. Web Components are built off of HTML Elements. They are not replaced when rendered the way they are in JavaScript component frameworks. Web components are quite literally HTML elements and have to obey HTML rules. For example: <!-- Nope --> <ul> <my-list-item></my-list-item> <!-- etc. --> </ul> <!-- Yep --> <ul> <li> <my-list-item></my-list-item> </li> </ul> We’re generating meaningful HTML up-front rather than rendering it in the browser through the client after the fact. Provide the markup and enhance it! Web components have been around a while now, even if it seems we’re only starting to talk about them now. Chapter 2: Custom Elements First off, custom elements are not built-in HTML elements. We instruct what they are and how they behave. They are named with a dash and at must contain least one letter. All of the following are valid names for custom elements: <super-component> <a-> <a-4-> <card-10.0.1> <card-♠️> Just remember that there are some reserved names for MathML and SVG elements, like <font-face>. Also, they cannot be void elements, e.g. <my-element />, meaning they have to have a correspoonding closing tag. Since custom elements are not built-in elements, they are undefined by default — and being undefined can be a useful thing! That means we can use them as containers with default properties. For example, they are display: inline by default and inherit the current font-family, which can be useful to pass down to the contents. We can also use them as styling hooks since they can be selected in CSS. Or maybe they can be used for accessibility hints. The bottom line is that they do not require JavaScript in order to make them immediately useful. Working with JavaScript. If there is one <my-button> on the page, we can query it and set a click handler on it with an event listener. But if we were to insert more instances on the page later, we would need to query it when it’s appended and re-run the function since it is not part of the original document rendering. Defining a custom element This defines and registers the custom element. It teaches the browser that this is an instance of the Custom Elements API and extends the same class that makes other HTML elements valid HTML elements: <my-element>My Element</my-element> <script> customElements.define("my-element", class extends HTMLElement {}); </script> Check out the methods we get immediate access to: Breaking down the syntax customElements .define( "my-element", class extends HTMLElement {} ); // Functionally the same as: class MyElement extends HTMLElement {} customElements.define("my-element", MyElement); export default myElement // ...which makes it importable by other elements: import MyElement from './MyElement.js'; const myElement = new MyElement(); document.body.appendChild(myElement); // <body> // <my-element></my-element> // </body> // Or simply pull it into a page // Don't need to `export default` but it doesn't hurt to leave it // <my-element>My Element</my-element> // <script type="module" src="my-element.js"></script> It’s possible to define a custom element by extending a specific HTML element. The specification documents this, but Scott is focusing on the primary way. class WordCount extends HTMLParagraphElement customElements.define("word-count", WordCount, { extends: "p" }); // <p is="word-count">This is a custom paragraph!</p> Scott says do not use this because WebKit is not going to implement it. We would have to polyfill it forever, or as long as WebKit holds out. Consider it a dead end. The lifecycle A component has various moments in its “life” span: Constructed (constructor) Connected (connectedCallback) Adopted (adoptedCallback) Attribute Changed (attributeChangedCallback) Disconnected (disconnectedCallback) We can hook into these to define the element’s behavior. class myElement extends HTMLElement { constructor() {} connectedCallback() {} adoptedCallback() {} attributeChangedCallback() {} disconnectedCallback() {} } customElements.define("my-element", MyElement); constructor() class myElement extends HTMLElement { constructor() { // provides us with the `this` keyword super() // add a property this.someProperty = "Some value goes here"; // add event listener this.addEventListener("click", () => {}); } } customElements.define("my-element", MyElement); “When the constructor is called, do this…” We don’t have to have a constructor when working with custom elements, but if we do, then we need to call super() because we’re extending another class and we’ll get all of those properties. Constructor is useful, but not for a lot of things. It’s useful for setting up initial state, registering default properties, adding event listeners, and even creating Shadow DOM (which Scott will get into in a later module). For example, we are unable to sniff out whether or not the custom element is in another element because we don’t know anything about its parent container yet (that’s where other lifecycle methods come into play) — we’ve merely defined it. connectedCallback() class myElement extends HTMLElement { // the constructor is unnecessary in this example but doesn't hurt. constructor() { super() } // let me know when my element has been found on the page. connectedCallback() { console.log(`${this.nodeName} was added to the page.`); } } customElements.define("my-element", MyElement); Note that there is some strangeness when it comes to timing things. Sometimes isConnected returns true during the constructor. connectedCallback() is our best way to know when the component is found on the page. This is the moment it is connected to the DOM. Use it to attach event listeners. If the <script> tag comes before the DOM is parsed, then it might not recognize childNodes. This is not an uncommon situation. But if we add type="module" to the <script>, then the script is deferred and we get the child nodes. Using setTimeout can also work, but it looks a little gross. disconnectedCallback class myElement extends HTMLElement { // let me know when my element has been found on the page. disconnectedCallback() { console.log(`${this.nodeName} was removed from the page.`); } } customElements.define("my-element", MyElement); This is useful when the component needs to be cleaned up, perhaps like stopping an animation or preventing memory links. adoptedCallback() This is when the component is adopted by another document or page. Say you have some iframes on a page and move a custom element from the page into an iframe, then it would be adopted in that scenario. It would be created, then added, then removed, then adopted, then added again. That’s a full lifecycle! This callback is adopted automatically simply by picking it up and dragging it between documents in the DOM. Custom elements and attributes Unlike React, HTML attributes are strings (not props!). Global attributes work as you’d expect, though some global attributes are reflected as properties. You can make any attribute do that if you want, just be sure to use care and caution when naming because, well, we don’t want any conflicts. Avoid standard attributes on a custom element as well, as that can be confusing particularly when handing a component to another developer. Example: using type as an attribute which is also used by <input> elements. We could say data-type instead. (Remember that Chris has a comprehensive guide on using data attributes.) Examples Here’s a quick example showing how to get a greeting attribute and set it on the custom element: class MyElement extends HTMLElement { get greeting() { return this.getAttribute('greeting'); // return this.hasAttribute('greeting'); } set greeting(val) { if(val) { this.setAttribute('greeting', val); // this setAttribute('greeting', ''); } else { this.removeAttribute('greeting'); } } } customElements.define("my-element", MyElement); Another example, this time showing a callback for when the attribute has changed, which prints it in the element’s contents: <my-element greeting="hello">hello</my-element> <!-- Change text greeting when attribite greeting changes --> <script> class MyElement extends HTMLElement { static observedAttributes = ["greeting"]; attributeChangedCallback(name, oldValue, newValue) { if (name === 'greeting' && oldValue && oldValue !== newValue) { console.log(name + " changed"); this.textContent = newValue; } } } customElements.define("my-element", MyElement); </script> A few more custom element methods: customElements.get('my-element'); // returns MyElement Class customElements.getName(MyElement); // returns 'my-element' customElements.whenDefined("my-element"); // waits for custom element to be defined const el = document.createElement("spider-man"); class SpiderMan extends HTMLElement { constructor() { super(); console.log("constructor!!"); } } customElements.define("spider-man", SpiderMan); customElements.upgrade(el); // returns "constructor!!" Custom methods and events: <my-element><button>My Element</button></my-element> <script> customElements.define("my-element", class extends HTMLElement { connectedCallback() { const btn = this.firstElementChild; btn.addEventListener("click", this.handleClick) } handleClick() { console.log(this); } }); </script> Bring your own base class, in the same way web components frameworks like Lit do: class BaseElement extends HTMLElement { $ = this.querySelector; } // extend the base, use its helper class myElement extends BaseElement { firstLi = this.$("li"); } Practice prompt Create a custom HTML element called <say-hi> that displays the text “Hi, World!” when added to the page: CodePen Embed Fallback Enhance the element to accept a name attribute, displaying "Hi, [Name]!" instead: CodePen Embed Fallback Chapter 3: HTML Templates The <template> element is not for users but developers. It is not exposed visibly by browsers. <template>The browser ignores everything in here.</template> Templates are designed to hold HTML fragments: <template> <div class="user-profile"> <h2 class="name">Scott</h2> <p class="bio">Author</p> </div> </template> A template is selectable in CSS; it just doesn’t render. It’s a document fragment. The inner document is a #document-fragment. Not sure why you’d do this, but it illustrates the point that templates are selectable: template { display: block; }` /* Nope */ template + div { height: 100px; width: 100px; } /* Works */ The content property No, not in CSS, but JavaScript. We can query the inner contents of a template and print them somewhere else. <template> <p>Hi</p> </template> <script> const myTmpl = documenty.querySelector("template").content; console.log(myTmpl); </script> Using a Document Fragment without a <template> const myFrag = document.createDocumentFragment(); myFrag.innerHTML = "<p>Test</p>"; // Nope const myP = document.createElement("p"); // Yep myP.textContent = "Hi!"; myFrag.append(myP); // use the fragment document.body.append(myFrag); Clone a node <template> <p>Hi</p> </template> <script> const myTmpl = documenty.querySelector("template").content; console.log(myTmpl); // Oops, only works one time! We need to clone it. </script> Oops, the component only works one time! We need to clone it if we want multiple instances: <template> <p>Hi</p> </template> <script> const myTmpl = document.querySelector("template").content; document.body.append(myTmpl.cloneNode(true)); // true is necessary document.body.append(myTmpl.cloneNode(true)); document.body.append(myTmpl.cloneNode(true)); document.body.append(myTmpl.cloneNode(true)); </script> A more practical example Let’s stub out a template for a list item and then insert them into an unordered list: <template id="tmpl-user"><li><strong></strong>: <span></span></li></template> <ul id="users"></ul> <script> const usersElement = document.querySelector("#users"); const userTmpl = document.querySelector("#tmpl-user").content; const users = [{name: "Bob", title: "Artist"}, {name: "Jane", title: "Doctor"}]; users.forEach(user => { let thisLi = userTmpl.cloneNode(true); thisLi.querySelector("strong").textContent = user.name; thisLi.querySelector("span").textContent = user.title; usersElement.append(thisLi); }); </script> The other way to use templates that we’ll get to in the next module: Shadow DOM <template shadowroot=open> <p>Hi, I'm in the Shadow DOM</p> </template> Chapter 4: Shadow DOM Here we go, this is a heady chapter! The Shadow DOM reminds me of playing bass in a band: it’s easy to understand but incredibly difficult to master. It’s easy to understand that there are these nodes in the DOM that are encapsulated from everything else. They’re there, we just can’t really touch them with regular CSS and JavaScript without some finagling. It’s the finagling that’s difficult to master. There are times when the Shadow DOM is going to be your best friend because it prevents outside styles and scripts from leaking in and mucking things up. Then again, you’re most certainly going go want to style or apply scripts to those nodes and you have to figure that part out. That’s where web components really shine. We get the benefits of an element that’s encapsulated from outside noise but we’re left with the responsibility of defining everything for it ourselves. Select elements are a great example of the Shadow DOM. Shadow roots! Slots! They’re all part of the puzzle. Using the Shadow DOM We covered the <template> element in the last chapter and determined that it renders in the Shadow DOM without getting displayed on the page. <template shadowrootmode="closed"> <p>This will render in the Shadow DOM.</p> </template> In this case, the <template> is rendered as a #shadow-root without the <template> element’s tags. It’s a fragment of code. So, while the paragraph inside the template is rendered, the <template> itself is not. It effectively marks the Shadow DOM’s boundaries. If we were to omit the shadowrootmode attribute, then we simply get an unrendered template. Either way, though, the paragraph is there in the DOM and it is encapsulated from other styles and scripts on the page. These are all of the elements that can have a shadow. Breaching the shadow There are times you’re going to want to “pierce” the Shadow DOM to allow for some styling and scripts. The content is relatively protected but we can open the shadowrootmode and allow some access. <div> <template shadowrootmode="open"> <p>This will render in the Shadow DOM.</p> </template> </div> Now we can query the div that contains the <template> and select the #shadow-root: document.querySelector("div").shadowRoot // #shadow-root (open) // <p>This will render in the Shadow DOM.</p> We need that <div> in there so we have something to query in the DOM to get to the paragraph. Remember, the <template> is not actually rendered at all. Additional shadow attributes <!-- should this root stay with a parent clone? --> <template shadowrootcloneable> <!-- allow shadow to be serialized into a string object — can forget about this --> <template shadowrootserializable> <!-- click in element focuses first focusable element --> <template shadowrootdelegatesfocus> Shadow DOM siblings When you add a shadow root, it becomes the only rendered root in that shadow host. Any elements after a shadow root node in the DOM simply don’t render. If a DOM element contains more than one shadow root node, the ones after the first just become template tags. It’s sort of like the Shadow DOM is a monster that eats the siblings. Slots bring those siblings back! <div> <template shadowroot="closed"> <slot></slot> <p>I'm a sibling of a shadow root, and I am visible.</p> </template> </div> All of the siblings go through the slots and are distributed that way. It’s sort of like slots allow us to open the monster’s mouth and see what’s inside. Declaring the Shadow DOM Using templates is the declarative way to define the Shadow DOM. We can also define the Shadow DOM imperatively using JavaScript. So, this is doing the exact same thing as the last code snippet, only it’s done programmatically in JavaScript: <my-element> <template shadowroot="open"> <p>This will render in the Shadow DOM.</p> </template> </my-element> <script> customElements.define('my-element', class extends HTMLElement { constructor() { super(); // attaches a shadow root node this.attachShadow({mode: "open"}); // inserts a slot into the template this.shadowRoot.innerHTML = '<slot></slot>'; } }); </script> Another example: <my-status>available</my-status> <script> customElements.define('my-status', class extends HTMLElement { constructor() { super(); this.attachShadow({mode: "open"}); this.shadowRoot.innerHTML = '<p>This item is currently: <slot></slot></p>'; } }); </script> So, is it better to be declarative or imperative? Like the weather where I live, it just depends. Both approaches have their benefits. We can set the shadow mode via Javascript as well: // open this.attachShadow({mode: open}); // closed this.attachShadow({mode: closed}); // cloneable this.attachShadow({cloneable: true}); // delegateFocus this.attachShadow({delegatesFocus: true}); // serialized this.attachShadow({serializable: true}); // Manually assign an element to a slot this.attachShadow({slotAssignment: "manual"}); About that last one, it says we have to manually insert the <slot> elements in JavaScript: <my-element> <p>This WILL render in shadow DOM but not automatically.</p> </my-element> <script> customElements.define('my-element', class extends HTMLElement { constructor() { super(); this.attachShadow({ mode: "open", slotAssignment: "manual" }); this.shadowRoot.innerHTML = '<slot></slot>'; } connectedCallback(){ const slotElem = this.querySelector('p'); this.shadowRoot.querySelector('slot').assign(slotElem); } }); </script> Examples Scott spent a great deal of time sharing examples that demonstrate different sorts of things you might want to do with the Shadow DOM when working with web components. I’ll rapid-fire those in here. Get an array of element nodes in a slot this.shadowRoot.querySelector('slot') .assignedElements(); // get an array of all nodes in a slot, text too this.shadowRoot.querySelector('slot') .assignedNodes(); When did a slot’s nodes change? let slot = document.querySelector('div') .shadowRoot.querySelector("slot"); slot.addEventListener("slotchange", (e) => { console.log(`Slot "${slot.name}" changed`); // > Slot "saying" changed }) Combining imperative Shadow DOM with templates Back to this example: <my-status>available</my-status> <script> customElements.define('my-status', class extends HTMLElement { constructor() { super(); this.attachShadow({mode: "open"}); this.shadowRoot.innerHTML = '<p>This item is currently: <slot></slot></p>'; } }); </script> Let’s get that string out of our JavaScript with reusable imperative shadow HTML: <my-status>available</my-status> <template id="my-status"> <p>This item is currently: <slot></slot> </p> </template> <script> customElements.define('my-status', class extends HTMLElement { constructor(){ super(); this.attachShadow({mode: 'open'}); const template = document.getElementById('my-status'); this.shadowRoot.append(template.content.cloneNode(true)); } }); </script> Slightly better as it grabs the component’s name programmatically to prevent name collisions: <my-status>available</my-status> <template id="my-status"> <p>This item is currently: <slot></slot> </p> </template> <script> customElements.define('my-status', class extends HTMLElement { constructor(){ super(); this.attachShadow({mode: 'open'}); const template = document.getElementById( this.nodeName.toLowerCase() ); this.shadowRoot.append(template.content.cloneNode(true)); } }); </script> Forms with Shadow DOM Long story, cut short: maybe don’t create custom form controls as web components. We get a lot of free features and functionalities — including accessibility — with native form controls that we have to recreate from scratch if we decide to roll our own. In the case of forms, one of the oddities of encapsulation is that form submissions are not automatically connected. Let’s look at a broken form that contains a web component for a custom input: <form> <my-input> <template shadowrootmode="open"> <label> <slot></slot> <input type="text" name="your-name"> </label> </template> Type your name! </my-input> <label><input type="checkbox" name="remember">Remember Me</label> <button>Submit</button> </form> <script> document.forms[0].addEventListener('input', function(){ let data = new FormData(this); console.log(new URLSearchParams(data).toString()); }); </script> This input’s value won’t be in the submission! Also, form validation and states are not communicated in the Shadow DOM. Similar connectivity issues with accessibility, where the shadow boundary can interfere with ARIA. For example, IDs are local to the Shadow DOM. Consider how much you really need the Shadow DOM when working with forms. Element internals The moral of the last section is to tread carefully when creating your own web components for form controls. Scott suggests avoiding that altogether, but he continued to demonstrate how we could theoretically fix functional and accessibility issues using element internals. Let’s start with an input value that will be included in the form submission. <form> <my-input name="name"></my-input> <button>Submit</button> </form> Now let’s slot this imperatively: <script> customElements.define('my-input', class extends HTMLElement { constructor() { super(); this.attachShadow({mode: 'open'}); this.shadowRoot.innerHTML = '<label><slot></slot><input type="text"></label>' } }); </script> The value is not communicated yet. We’ll add a static formAssociated variable with internals attached: <script> customElements.define('my-input', class extends HTMLElement { static formAssociated = true; constructor() { super(); this.attachShadow({mode: 'open'}); this.shadowRoot.innerHTML = '<label><slot></slot><input type="text"></label>' this.internals = this.attachedInternals(); } }); </script> Then we’ll set the form value as part of the internals when the input’s value changes: <script> customElements.define('my-input', class extends HTMLElement { static formAssociated = true; constructor() { super(); this.attachShadow({mode: 'open'}); this.shadowRoot.innerHTML = '<label><slot></slot><input type="text"></label>' this.internals = this.attachedInternals(); this.addEventListener('input', () => { this-internals.setFormValue(this.shadowRoot.querySelector('input').value); }); } }); </script> Here’s how we set states with element internals: // add a checked state this.internals.states.add("checked"); // remove a checked state this.internals.states.delete("checked"); Let’s toggle a “add” or “delete” a boolean state: <form> <my-check name="remember">Remember Me?</my-check> </form> <script> customElements.define('my-check', class extends HTMLElement { static formAssociated = true; constructor(){ super(); this.attachShadow({mode: 'open'}); this.shadowRoot.innerHTML = '<slot></slot>'; this.internals = this.attachInternals(); let addDelete = false; this.addEventListener("click", ()=> { addDelete = !addDelete; this.internals.states[addDelete ? "add" : "delete"]("checked"); } ); } }); </script> Let’s refactor this for ARIA improvements: <form> <style> my-check { display: inline-block; inline-size: 1em; block-size: 1em; background: #eee; } my-check:state(checked)::before { content: "[x]"; } </style> <my-check name="remember" id="remember"></my-check><label for="remember">Remember Me?</label> </form> <script> customElements.define('my-check', class extends HTMLElement { static formAssociated = true; constructor(){ super(); this.attachShadow({mode: 'open'}); this.internals = this.attachInternals(); this.internals.role = 'checkbox'; this.setAttribute('tabindex', '0'); let addDelete = false; this.addEventListener("click", ()=> { addDelete = !addDelete; this.internals.states[addDelete ? "add" : "delete"]("checked"); this[addDelete ? "setAttribute" : "removeAttribute"]("aria-checked", true); }); } }); </script> Phew, that’s a lot of work! And sure, this gets us a lot closer to a more functional and accessible custom form input, but there’s still a long way’s to go to achieve what we already get for free from using native form controls. Always question whether you can rely on a light DOM form instead. Chapter 5: Styling Web Components Styling web components comes in levels of complexity. For example, we don’t need any JavaScript at all to slap a few styles on a custom element. <my-element theme="suave" class="priority"> <h1>I'm in the Light DOM!</h1> </my-element> <style> /* Element, class, attribute, and complex selectors all work. */ my-element { display: block; /* custom elements are inline by default */ } .my-element[theme=suave] { color: #fff; } .my-element.priority { background: purple; } .my-element h1 { font-size: 3rem; } </style> This is not encapsulated! This is scoped off of a single element just light any other CSS in the Light DOM. Changing the Shadow DOM mode from closed to open doesn’t change CSS. It allows JavaScript to pierce the Shadow DOM but CSS isn’t affected. Let’s poke at it <style> p { color: red; } </style> <p>Hi</p> <div> <template shadowrootmode="open"> <p>Hi</p> </template> </div> <p>Hi</p> This is three stacked paragraphs, the second of which is in the shadow root. The first and third paragraphs are red; the second is not styled because it is in a <template>, even if the shadow root’s mode is set to open. Let’s poke at it from the other direction: <style> p { color: red; } </style> <p>Hi</p> <div> <template shadowrootmode="open"> <style> p { color: blue;} </style> <p>Hi</p> </template> </div> <p>Hi</p> The first and third paragraphs are still receiving the red color from the Light DOM’s CSS. The <style> declarations in the <template> are encapsulated and do not leak out to the other paragraphs, even though it is declared later in the cascade. Same idea, but setting the color on the <body>: <style> body { color: red; } </style> <p>Hi</p> <div> <template shadowrootmode="open"> <p>Hi</p> </template> </div> <p>Hi</p> Everything is red! This isn’t a bug. Inheritable styles do pass through the Shadow DOM barrier. Inherited styles are those that are set by the computed values of their parent styles. Many properties are inheritable, including color. The <body> is the parent and everything in it is a child that inherits these styles, including custom elements. Let’s fight with inheritance We can target the paragraph in the <template> style block to override the styles set on the <body>. Those won’t leak back to the other paragraphs. <style> body { color: red; font-family: fantasy; font-size: 2em; } </style> <p>Hi</p> <div> <template shadowrootmode="open"> <style> /* reset the light dom styles */ p { color: initial; font-family: initial; font-size: initial; } </style> <p>Hi</p> </template> </div> <p>Hi</p> This is protected, but the problem here is that it’s still possible for a new role or property to be introduced that passes along inherited styles that we haven’t thought to reset. Perhaps we could use all: initital as a defensive strategy against future inheritable styles. But what if we add more elements to the custom element? It’s a constant fight. Host styles! We can scope things to the shadow root’s :host selector to keep things protected. <style> body { color: red; font-family: fantasy; font-size: 2em; } </style> <p>Hi</p> <div> <template shadowrootmode="open"> <style> /* reset the light dom styles */ :host { all: initial; } </style> <p>Hi</p> <a href="#">Click me</a> </template> </div> <p>Hi</p> New problem! What if the Light DOM styles are scoped to the universal selector instead? <style> * { color: red; font-family: fantasy; font-size: 2em; } </style> <p>Hi</p> <div> <template shadowrootmode="open"> <style> /* reset the light dom styles */ :host { all: initial; } </style> <p>Hi</p> <a href="#">Click me</a> </template> </div> <p>Hi</p> This breaks the custom element’s styles. But that’s because Shadow DOM styles are applied before Light DOM styles. The styles scoped to the universal selector are simply applied after the :host styles, which overrides what we have in the shadow root. So, we’re still locked in a brutal fight over inheritance and need stronger specificity. According to Scott, !important is one of the only ways we have to apply brute force to protect our custom elements from outside styles leaking in. The keyword gets a bad rap — and rightfully so in the vast majority of cases — but this is a case where it works well and using it is an encouraged practice. It’s not like it has an impact on the styles outside the custom element, anyway. <style> * { color: red; font-family: fantasy; font-size: 2em; } </style> <p>Hi</p> <div> <template shadowrootmode="open"> <style> /* reset the light dom styles */ :host { all: initial; !important } </style> <p>Hi</p> <a href="#">Click me</a> </template> </div> <p>Hi</p> Special selectors There are some useful selectors we have to look at components from the outside, looking in. :host() We just looked at this! But note how it is a function in addition to being a pseudo-selector. It’s sort of a parent selector in the sense that we can pass in the <div> that contains the <template> and that becomes the scoping context for the entire selector, meaning the !important keyword is no longer needed. <style> * { color: red; font-family: fantasy; font-size: 2em; } </style> <p>Hi</p> <div> <template shadowrootmode="open"> <style> /* reset the light dom styles */ :host(div) { all: initial; } </style> <p>Hi</p> <a href="#">Click me</a> </template> </div> <p>Hi</p> :host-context() <header> <my-element> <template shadowrootmode="open"> <style> :host-context(header) { ... } /* matches the host! */ </style> </template> </my-element> </header> This targets the shadow host but only if the provided selector is a parent node anywhere up the tree. This is super helpful for styling custom elements where the layout context might change, say, from being contained in an <article> versus being contained in a <header>. :defined Defining an element occurs when it is created, and this pseudo-selector is how we can select the element in that initially-defined state. I imagine this is mostly useful for when a custom element is defined imperatively in JavaScript so that we can target the very moment that the element is constructed, and then set styles right then and there. <style> simple-custom:defined { display: block; background: green; color: #fff; } </style> <simple-custom></simple-custom> <script> customElements.define('simple-custom', class extends HTMLElement { constructor(){ super(); this.attachShadow({mode: 'open'}); this.shadowRoot.innerHTML = "<p>Defined!</p>"; } }); </script> Minor note about protecting against a flash of unstyled content (FOUC)… or unstyled element in this case. Some elements are effectively useless until JavsScript has interacted with it to generate content. For example, an empty custom element that only becomes meaningful once JavaScript runs and generates content. Here’s how we can prevent the inevitable flash that happens after the content is generated: <style> js-dependent-element:not(:defined) { visibility: hidden; } </style> <js-dependent-element></js-dependent-element> Warning zone! It’s best for elements that are empty and not yet defined. If you’re working with a meaningful element up-front, then it’s best to style as much as you can up-front. Styling slots This does not style the paragraph green as you might expect: <div> <template shadowrootmode="open"> <style> p { color: green; } </style> <slot></slot> </template> <p>Slotted Element</p> </div> The Shadow DOM cannot style this content directly. The styles would apply to a paragraph in the <template> that gets rendered in the Light DOM, but it cannot style it when it is slotted into the <template>. Slots are part of the Light DOM. So, this works: <style> p { color: green; } </style> <div> <template shadowrootmode="open"> <slot></slot> </template> <p>Slotted Element</p> </div> This means that slots are easier to target when it comes to piercing the shadow root with styles, making them a great method of progressive style enhancement. We have another special selected, the ::slotted() pseudo-element that’s also a function. We pass it an element or class and that allows us to select elements from within the shadow root. <div> <template shadowrootmode="open"> <style> ::slotted(p) { color: red; } </style> <slot></slot> </template> <p>Slotted Element</p> </div> Unfortunately, ::slotted() is a weak selected when compared to global selectors. So, if we were to make this a little more complicated by introducing an outside inheritable style, then we’d be hosed again. <style> /* global paragraph style... */ p { color: green; } </style> <div> <template shadowrootmode="open"> <style> /* ...overrides the slotted style */ ::slotted(p) { color: red; } </style> <slot></slot> </template> <p>Slotted Element</p> </div> This is another place where !important could make sense. It even wins if the global style is also set to !important. We could get more defensive and pass the universal selector to ::slotted and set everything back to its initial value so that all slotted content is encapsulated from outside styles leaking in. <style> /* global paragraph style... */ p { color: green; } </style> <div> <template shadowrootmode="open"> <style> /* ...can't override this important statement */ ::slotted(*) { all: initial !important; } </style> <slot></slot> </template> <p>Slotted Element</p> </div> Styling :parts A part is a way of offering up Shadow DOM elements to the parent document for styling. Let’s add a part to a custom element: <div> <template shadowrootmode="open"> <p part="hi">Hi there, I'm a part!</p> </template> </div> Without the part attribute, there is no way to write styles that reach the paragraph. But with it, the part is exposed as something that can be styled. <style> ::part(hi) { color: green; } ::part(hi) b { color: green; } /* nope! */ </style> <div> <template shadowrootmode="open"> <p part="hi">Hi there, I'm a <b>part</b>!</p> </template> </div> We can use this to expose specific “parts” of the custom element that are open to outside styling, which is almost like establishing a styling API with specifications for what can and can’t be styled. Just note that ::part cannot be used as part of a complex selector, like a descendant selector: A bit in the weeds here, but we can export parts in the sense that we can nest elements within elements within elements, and so on. This way, we include parts within elements. <my-component> <!-- exposes three parts to the nested component --> <nested-component exportparts="part1, part2, part5"></nested-component> </my-component> Styling states and validity We discussed this when going over element internals in the chapter about the Shadow DOM. But it’s worth revisiting that now that we’re specifically talking about styling. We have a :state pseudo-function that accepts our defined states. <script> this.internals.states.add("checked"); </script> <style> my-checkbox:state(checked) { /* ... */ } </style> We also have access to the :invalid pseudo-class. Cross-barrier custom properties <style> :root { --text-primary: navy; --bg-primary: #abe1e1; --padding: 1.5em 1em; } p { color: var(--text-primary); background: var(--bg-primary); padding: var(--padding); } </style> Custom properties cross the Shadow DOM barrier! <my-elem></my-elem> <script> customElements.define('my-elem', class extends HTMLElement { constructor(){ super(); this.attachShadow({mode: 'open'}); this.shadowRoot.innerHTML = ` <style> p { color: var(--text-primary); background: var(--bg-primary); padding: var(--padding); } </style> <p>Hi there!</p>`; } }) </script> Adding stylesheets to custom elements There’s the classic ol’ external <link> way of going about it: <simple-custom> <template shadowrootmode="open"> <link rel="stylesheet" href="../../assets/external.css"> <p>This one's in the shadow Dom.</p> <slot></slot> </template> <p>Slotted <b>Element</b></p> </simple-custom> It might seem like an anti-DRY approach to call the same external stylesheet at the top of all web components. To be clear, yes, it is repetitive — but only as far as writing it. Once the sheet has been downloaded once, it is available across the board without any additional requests, so we’re still technically dry in the sense of performance. CSS imports also work: <style> @import url("../../assets/external.css"); </style> <simple-custom> <template shadowrootmode="open"> <style> @import url("../../assets/external.css"); </style> <p>This one's in the shadow Dom.</p> <slot></slot> </template> <p>Slotted <b>Element</b></p> </simple-custom> One more way using a JavaScript-based approach. It’s probably better to make CSS work without a JavaScript dependency, but it’s still a valid option. <my-elem></my-elem> <script type="module"> import sheet from '../../assets/external.css' with { type: 'css' }; customElements.define('my-elem', class extends HTMLElement { constructor(){ super(); this.attachShadow({mode: 'open'}); this.shadowRoot.innerHTML = '<p>Hi there</p>'; this.shadowRoot.adoptedStyleSheets = [sheet]; } }) </script> We have a JavaScript module and import CSS into a string that is then adopted by the shadow root using shadowRoort.adoptedStyleSheets . And since adopted stylesheets are dynamic, we can construct one, share it across multiple instances, and update styles via the CSSOM that ripple across the board to all components that adopt it. Container queries! Container queries are nice to pair with components, as custom elements and web components are containers and we can query them and adjust things as the container changes. <div> <template shadowrootmode="open"> <style> :host { container-type: inline-size; background-color: tan; display: block; padding: 2em; } ul { display: block; list-style: none; margin: 0; } li { padding: .5em; margin: .5em 0; background-color: #fff; } @container (min-width: 50em) { ul { display: flex; justify-content: space-between; gap: 1em; } li { flex: 1 1 auto; } } </style> <ul> <li>First Item</li> <li>Second Item</li> </ul> </template> </div> In this example, we’re setting styles on the :host() to define a new container, as well as some general styles that are protected and scoped to the shadow root. From there, we introduce a container query that updates the unordered list’s layout when the custom element is at least 50em wide. Next up… How web component features are used together! Chapter 6: HTML-First Patterns In this chapter, Scott focuses on how other people are using web components in the wild and highlights a few of the more interesting and smart patterns he’s seen. Let’s start with a typical counter It’s often the very first example used in React tutorials. <counter-element></counter-element> <script type="module"> customElements.define('counter-element', class extends HTMLElement { #count = 0; connectedCallback() { this.innerHTML = `<button id="dec">-</button><p id="count">${this.#count}</p><button id="inc">+</button>`; this.addEventListener('click', e => this.update(e) ); } update(e) { if( e.target.nodeName !== 'BUTTON' ) { return } this.#count = e.target.id === 'inc' ? this.#count + 1 : this.#count - 1; this.querySelector('#count').textContent = this.#count; } }); </script> Reef Reef is a tiny library by Chris Ferdinandi that weighs just 2.6KB minified and zipped yet still provides DOM diffing for reactive state-based UIs like React, which weighs significantly more. An example of how it works in a standalone way: <div id="greeting"></div> <script type="module"> import {signal, component} from '.../reef.es..min.js'; // Create a signal let data = signal({ greeting: 'Hello', name: 'World' }); component('#greeting', () => `<p>${data.greeting}, ${data.name}!</p>`); </script> This sets up a “signal” that is basically a live-update object, then calls the component() method to select where we want to make the update, and it injects a template literal in there that passes in the variables with the markup we want. So, for example, we can update those values on setTimeout: <div id="greeting"></div> <script type="module"> import {signal, component} from '.../reef.es..min.js'; // Create a signal let data = signal({ greeting: 'Hello', name: 'World' }); component('#greeting', () => `<p>${data.greeting}, ${data.name}!</p>`); setTimeout(() => { data.greeting = '¡Hola' data,name = 'Scott' }, 3000) </script> We can combine this sort of library with a web component. Here, Scott imports Reef and constructs the data outside the component so that it’s like the application state: <my-greeting></my-greeting> <script type="module"> import {signal, component} from 'https://cdn.jsdelivr.net/npm/reefjs@13/dist/reef.es.min.js'; window.data = signal({ greeting: 'Hi', name: 'Scott' }); customElements.define('my-greeting', class extends HTMLElement { connectedCallback(){ component(this, () => `<p>${data.greeting}, ${data.name}!</p>` ); } }); </script> It’s the virtual DOM in a web component! Another approach that is more reactive in the sense that it watches for changes in attributes and then updates the application state in response which, in turn, updates the greeting. <my-greeting greeting="Hi" name="Scott"></my-greeting> <script type="module"> import {signal, component} from 'https://cdn.jsdelivr.net/npm/reefjs@13/dist/reef.es.min.js'; customElements.define('my-greeting', class extends HTMLElement { static observedAttributes = ["name", "greeting"]; constructor(){ super(); this.data = signal({ greeting: '', name: '' }); } attributeChangedCallback(name, oldValue, newValue) { this.data[name] = newValue; } connectedCallback(){ component(this, () => `<p>${this.data.greeting}, ${this.data.name}!</p>` ); } }); </script> If the attribute changes, it only changes that instance. The data is registered at the time the component is constructed and we’re only changing string attributes rather than objects with properties. HTML Web Components This describes web components that are not empty by default like this: <my-greeting></my-greeting> This is a “React” mindset where all the functionality, content, and behavior comes from JavaScript. But Scott reminds us that web components are pretty useful right out of the box without JavaScript. So, “HTML web components” refers to web components that are packed with meaningful content right out of the gate and Scott points to Jeremy Keith’s 2023 article coining the term. […] we could call them “HTML web components.” If your custom element is empty, it’s not an HTML web component. But if you’re using a custom element to extend existing markup, that’s an HTML web component. Jeremy cites something Robin Rendle mused about the distinction: […] I’ve started to come around and see Web Components as filling in the blanks of what we can do with hypertext: they’re really just small, reusable chunks of code that extends the language of HTML. The “React” way: <UserAvatar src="https://example.com/path/to/img.jpg" alt="..." /> The props look like HTML but they’re not. Instead, the props provide information used to completely swap out the <UserAvatar /> tag with the JavaScript-based markup. Web components can do that, too: <user-avatar src="https://example.com/path/to/img.jpg" alt="..." ></user-avatar> Same deal, real HTML. Progressive enhancement is at the heart of an HTML web component mindset. Here’s how that web component might work: class UserAvatar extends HTMLElement { connectedCallback() { const src = this.getAttribute("src"); const name = this.getAttribute("name"); this.innerHTML = ` <div> <img src="${src}" alt="Profile photo of ${name}" width="32" height="32" /> <!-- Markup for the tooltip --> </div> `; } } customElements.define('user-avatar', UserAvatar); But a better starting point would be to include the <img> directly in the component so that the markup is immediately available: <user-avatar> <img src="https://example.com/path/to/img.jpg" alt="..." /> </user-avatar> This way, the image is downloaded and ready before JavaScript even loads on the page. Strive for augmentation over replacement! resizeasaurus This helps developers test responsive component layouts, particularly ones that use container queries. <resize-asaurus> Drop any HTML in here to test. </resize-asaurus> <!-- for example: --> <resize-asaurus> <div class="my-responsive-grid"> <div>Cell 1</div> <div>Cell 2</div> <div>Cell 3</div> <!-- ... --> </div> </resize-asaurus> lite-youtube-embed This is like embedding a YouTube video, but without bringing along all the baggage that YouTube packs into a typical embed snippet. <lite-youtube videoid="ogYfd705cRs" style="background-image: url(...);"> <a href="https://youtube.com/watch?v=ogYfd705cRs" class="lyt-playbtn" title="Play Video"> <span class="lyt-visually-hidden">Play Video: Keynote (Google I/O '18)</span> </a> </lite-youtube> <link rel="stylesheet" href="./src.lite-yt-embed.css" /> <script src="./src.lite-yt-embed.js" defer></script> It starts with a link which is a nice fallback if the video fails to load for whatever reason. When the script runs, the HTML is augmented to include the video <iframe>. Chapter 7: Web Components Frameworks Tour Lit Lit extends the base class and then extends what that class provides, but you’re still working directly on top of web components. There are syntax shortcuts for common patterns and a more structured approach. The package includes all this in about 5-7KB: Fast templating Reactive properties Reactive update lifecycle Scoped styles <simple-greeting name="Geoff"></simple-greeting> <script> import {html, css, LitElement} from 'lit'; export class SimpleGreeting extends LitElement { state styles = css`p { color: blue }`; static properties = { name: {type = String}, }; constructor() { super(); this.name = 'Somebody'; } render() { return html`<p>Hello, ${this.name}!</p>`; } } customElements.define('simple-greeting', SimpleGreeting); </script> Pros Cons Ecosystem No official SSR story (but that is changing) Community Familiar ergonomics Lightweight Industry-proven webc This is part of the 11ty project. It allows you to define custom elements as files, writing everything as a single file component. <!-- starting element / index.html --> <my-element></my-element> <!-- ../components/my-element.webc --> <p>This is inside the element</p> <style> /* etc. */ </style> <script> // etc. </script> Pros Cons Community Geared toward SSG SSG progressive enhancement Still in early stages Single file component syntax Zach Leatherman! Enhance This is Scott’s favorite! It renders web components on the server. Web components can render based on application state per request. It’s a way to use custom elements on the server side. Pros Cons Ergonomics Still in early stages Progressive enhancement Single file component syntax Full-stack stateful, dynamic SSR components Chapter 8: Web Components Libraries Tour This is a super short module simply highlighting a few of the more notable libraries for web components that are offered by third parties. Scott is quick to note that all of them are closer in spirit to a React-based approach where custom elements are more like replaced elements with very little meaningful markup to display up-front. That’s not to throw shade at the libraries, but rather to call out that there’s a cost when we require JavaScript to render meaningful content. Spectrum <sp-button variant="accent" href="components/button"> Use Spectrum Web Component buttons </sp-button> This is Adobe’s design system. One of the more ambitious projects, as it supports other frameworks like React Open source Built on Lit Most components are not exactly HTML-first. The pattern is closer to replaced elements. There’s plenty of complexity, but that makes sense for a system that drives an application like Photoshop and is meant to drop into any project. But still, there is a cost when it comes to delivering meaningful content to users up-front. An all-or-nothing approach like this might be too stark for a small website project. FAST <fast-checkbox>Checkbox</fast-checkbox> This is Microsoft’s system. It’s philosophically like Spectrum where there’s very little meaningful HTML up-front. Fluent is a library that extends the system for UI components. Microsoft Edge rebuilt the browser’s Chrome using these components. Shoelace <sl-button>Click Me</sl-button> Purely meant for third-party developers to use in their projects The name is a play on Bootstrap. 🙂 The markup is mostly a custom element with some text in it rather than a pure HTML-first approach. Acquired by Font Awesome and they are creating Web Awesome Components as a new era of Shoelace that is subscription-based Chapter 9: What’s Next With Web Components Scott covers what the future holds for web components as far as he is aware. Declarative custom elements Define an element in HTML alone that can be used time and again with a simpler syntax. There’s a GitHub issue that explains the idea, and Zach Leatherman has a great write-up as well. GitHub Issue Cross-root ARIA Make it easier to pair custom elements with other elements in the Light DOM as well as other custom elements through ARIA. GitHub Explainer GitHub Proposal Container Queries How can we use container queries without needing an extra wrapper around the custom element? HTML Modules This was one of the web components’ core features but was removed at some point. They can define HTML in an external place that could be used over and over. GitHub Explainer External styling This is also known as “open styling.” GitHub Explainer DOM Parts This would be a templating feature that allows for JSX-string-literal-like syntax where variables inject data. <section> <h1 id="name">{name}</h1> Email: <a id="link" href="mailto:{email}">{email}</a> </section> And the application has produced a template with the following content: <template> <section> <h1 id="name">{{}}</h1> Email: <a id="link" href="{{}}">{{}}</a> </section> </template> GitHub Proposal Scoped element registries Using variations of the same web component without name collisions. GitHub Issue Web Components Demystified originally published on CSS-Tricks, which is part of the DigitalOcean family. You should get the newsletter.

                                                                                                                                                                                                                                                                                                                                                                    Powering Search With Astro Actions and Fuse.js

                                                                                                                                                                                                                                                                                                                                                                    • Articles
                                                                                                                                                                                                                                                                                                                                                                    • astro
                                                                                                                                                                                                                                                                                                                                                                    • static site generators

                                                                                                                                                                                                                                                                                                                                                                    With Astro, we can generate most of our site during our build, but have a small bit of server-side code that can handle search functionality using something like Fuse.js. In this demo, we’ll use Fuse to search through a set of personal “bookmarks” that are generated at build time, but return back proper results from a server call.

                                                                                                                                                                                                                                                                                                                                                                    Powering Search With Astro Actions and Fuse.js originally published on CSS-Tricks, which is part of the DigitalOcean family. You should get the newsletter.

                                                                                                                                                                                                                                                                                                                                                                    Static sites are wonderful. I’m a big fan. They also have their issues. Namely, static sites either are purely static or the frameworks that generate them completely lose out on true static generation when you just dip your toes in the direction of server routes. Astro has been watching the front-end ecosystem and is trying to keep one foot firmly embedded in pure static generation, and the other in a powerful set of server-side functionality. With Astro Actions, Astro brings a lot of the power of the server to a site that is almost entirely static. A good example of this sort of functionality is dealing with search. If you have a content-based site that can be purely generated, adding search is either going to be something handled entirely on the front end, via a software-as-a-service solution, or, in other frameworks, converting your entire site to a server-side application. With Astro, we can generate most of our site during our build, but have a small bit of server-side code that can handle our search functionality using something like Fuse.js. In this demo, we’ll use Fuse to search through a set of personal “bookmarks” that are generated at build time, but return proper results from a server call. GitHub Live Demo Starting the project To get started, we’ll just set up a very basic Astro project. In your terminal, run the following command: npm create astro@latest Astro’s adorable mascot Houston is going to ask you a few questions in your terminal. Here are the basic responses, you’ll need: Where should we create your new project? Wherever you’d like, but I’ll be calling my directory ./astro-search How would you like to start your new project? Choose the basic minimalist starter. Install dependencies? Yes, please! Initialize a new git repository? I’d recommend it, personally! This will create a directory in the location specified and install everything you need to start an Astro project. Open the directory in your code editor of choice and run npm run dev in your terminal in the directory. When you run your project, you’ll see the default Astro project homepage. We’re ready to get our project rolling! Basic setup To get started, let’s remove the default content from the homepage. Open the /src/pages/index.astro file. This is a fairly barebones homepage, but we want it to be even more basic. Remove the <Welcome /> component, and we’ll have a nice blank page. For styling, let’s add Tailwind and some very basic markup to the homepage to contain our site. npx astro add tailwind The astro add command will install Tailwind and attempt to set up all the boilerplate code for you (handy!). The CLI will ask you if you want it to add the various components, I recommend letting it, but if anything fails, you can copy the code needed from each of the steps in the process. As the last step for getting to work with Tailwind, the CLI will tell you to import the styles into a shared layout. Follow those instructions, and we can get to work. Let’s add some very basic markup to our new homepage. --- // ./src/pages/index.astro import Layout from '../layouts/Layout.astro'; --- <Layout> <div class="max-w-3xl mx-auto my-10"> <h1 class="text-3xl text-center">My latest bookmarks</h1> <p class="text-xl text-center mb-5">This is only 10 of A LARGE NUMBER THAT WE'LL CHANGE LATER</p> </div> </Layout> Your site should now look like this. Not exactly winning any awards yet! That’s alright. Let’s get our bookmarks loaded in. Adding bookmark data with Astro Content Layer Since not everyone runs their own application for bookmarking interesting items, you can borrow my data. Here’s a small subset of my bookmarks, or you can go get 110 items from this link on GitHub. Add this data as a file in your project. I like to group data in a data directory, so my file lives in /src/data/bookmarks.json. Open code [ { "pageTitle": "Our Favorite Sandwich Bread | King Arthur Baking", "url": "<https://www.kingarthurbaking.com/recipes/our-favorite-sandwich-bread-recipe>", "description": "Classic American sandwich loaf, perfect for French toast and sandwiches.", "id": "007y8pmEOvhwldfT3wx1MW" }, { "pageTitle": "Chris Coyier's discussion of Automatic Social Share Images | CSS-Tricks ", "url": "<https://css-tricks.com/automatic-social-share-images/>", "description": "It's a pretty low-effort thing to get a big fancy link preview on social media. Toss a handful of specific <meta> tags on a URL and you get a big image-title-description thing ", "id": "04CXDvGQo19m0oXERL6bhF" }, { "pageTitle": "Automatic Social Share Images | ryanfiller.com", "url": "<https://www.ryanfiller.com/blog/automatic-social-share-images/>", "description": "Setting up automatic social share images with Puppeteer and Netlify Functions. ", "id": "04CXDvGQo19m0oXERLoC10" }, { "pageTitle": "Emma Wedekind: Foundations of Design Systems / React Boston 2019 - YouTube", "url": "<https://m.youtube.com/watch?v=pXb2jA43A6k>", "description": "Emma Wedekind: Foundations of Design Systems / React Boston 2019 Presented by: Emma Wedekind – LogMeIn Design systems are in the world around us, from street...", "id": "0d56d03e-aba4-4ebd-9db8-644bcc185e33" }, { "pageTitle": "Editorial Design Patterns With CSS Grid And Named Columns — Smashing Magazine", "url": "<https://www.smashingmagazine.com/2019/10/editorial-design-patterns-css-grid-subgrid-naming/>", "description": "By naming lines when setting up our CSS Grid layouts, we can tap into some interesting and useful features of Grid — features that become even more powerful when we introduce subgrids.", "id": "13ac1043-1b7d-4a5b-a3d8-b6f5ec34cf1c" }, { "pageTitle": "Netlify pro tip: Using Split Testing to power private beta releases - DEV Community 👩‍💻👨‍💻", "url": "<https://dev.to/philhawksworth/netlify-pro-tip-using-split-testing-to-power-private-beta-releases-a7l>", "description": "Giving users ways to opt in and out of your private betas. Video and tutorial.", "id": "1fbabbf9-2952-47f2-9005-25af90b0229e" }, { "pageTitle": "Netlify Public Folder, Part I: What? Recreating the Dropbox Public Folder With Netlify | Jim Nielsen’s Weblog", "url": "<https://blog.jim-nielsen.com/2019/netlify-public-folder-part-i-what/>", "id": "2607e651-7b64-4695-8af9-3b9b88d402d5" }, { "pageTitle": "Why Is CSS So Weird? - YouTube", "url": "<https://m.youtube.com/watch?v=aHUtMbJw8iA&feature=youtu.be>", "description": "Love it or hate it, CSS is weird! It doesn't work like most programming languages, and it doesn't work like a design tool either. But CSS is also solving a v...", "id": "2e29aa3b-45b8-4ce4-85b7-fd8bc50daccd" }, { "pageTitle": "Internet world despairs as non-profit .org sold for $$$$ to private equity firm, price caps axed • The Register", "url": "<https://www.theregister.co.uk/2019/11/20/org_registry_sale_shambles/>", "id": "33406b33-c453-44d3-8b18-2d2ae83ee73f" }, { "pageTitle": "Netlify Identity for paid subscriptions - Access Control / Identity - Netlify Community", "url": "<https://community.netlify.com/t/netlify-identity-for-paid-subscriptions/1947/2>", "description": "I want to limit certain functionality on my website to paying users. Now I’m using a payment provider (Mollie) similar to Stripe. My idea was to use the webhook fired by this service to call a Netlify function and give…", "id": "34d6341c-18eb-4744-88e1-cfbf6c1cfa6c" }, { "pageTitle": "SmashingConf Freiburg 2019: Videos And Photos — Smashing Magazine", "url": "<https://www.smashingmagazine.com/2019/10/smashingconf-freiburg-2019/>", "description": "We had a lovely time at SmashingConf Freiburg. This post wraps up the event and also shares the video of all of the Freiburg presentations.", "id": "354cbb34-b24a-47f1-8973-8553ed1d809d" }, { "pageTitle": "Adding Google Calendar to your JAMStack", "url": "<https://www.raymondcamden.com/2019/11/18/adding-google-calendar-to-your-jamstack>", "description": "A look at using Google APIs to add events to your static site.", "id": "361b20c4-75ce-46b3-b6d9-38139e03f2ca" }, { "pageTitle": "How to Contribute to an Open Source Project | CSS-Tricks", "url": "<https://css-tricks.com/how-to-contribute-to-an-open-source-project/>", "description": "The following is going to get slightly opinionated and aims to guide someone on their journey into open source. As a prerequisite, you should have basic", "id": "37300606-af08-4d9a-b5e3-12f64ebbb505" }, { "pageTitle": "Functions | Netlify", "url": "<https://www.netlify.com/docs/functions/>", "description": "Netlify builds, deploys, and hosts your front end. Learn how to get started, see examples, and view documentation for the modern web platform.", "id": "3bf9e31b-5288-4b3b-89f2-97034603dbf6" }, { "pageTitle": "Serverless Can Help You To Focus - By Simona Cotin", "url": "<https://hackernoon.com/serverless-can-do-that-7nw32mk>", "id": "43b1ee63-c2f8-4e14-8700-1e21c2e0a8b1" }, { "pageTitle": "Nuxt, Next, Nest?! My Head Hurts. - DEV Community 👩‍💻👨‍💻", "url": "<https://dev.to/laurieontech/nuxt-next-nest-my-head-hurts-5h98>", "description": "I clearly know what all of these things are. Their names are not at all similar. But let's review, just to make sure we know...", "id": "456b7d6d-7efa-408a-9eca-0325d996b69c" }, { "pageTitle": "Consuming a headless CMS GraphQL API with Eleventy - Webstoemp", "url": "<https://www.webstoemp.com/blog/headless-cms-graphql-api-eleventy/>", "description": "With Eleventy, consuming data coming from a GraphQL API to generate static pages is as easy as using Markdown files.", "id": "4606b168-21a6-49df-8536-a2a00750d659" }, ] Now that the data is in the project, we need for Astro to incorporate the data into its build process. To do this, we can use Astro’s new(ish) Content Layer API. The Content Layer API adds a content configuration file to your src directory that allows you to run and collect any number of content pieces from data in your project or external APIs. Create the file /src/content.config.ts (the name of this file matters, as this is what Astro is looking for in your project). import { defineCollection, z } from "astro:content"; import { file } from 'astro/loaders'; const bookmarks = defineCollection({ schema: z.object({ pageTitle: z.string(), url: z.string(), description: z.string().optional() }), loader: file("src/data/bookmarks.json"), }); export const collections = { bookmarks }; In this file, we import a few helpers from Astro. We can use defineCollection to create the collection, z as Zod, to help define our types, and file is a specific content loader meant to read data files. The defineCollection method takes an object as its argument with a required loader and optional schema. The schema will help make our content type-safe and make sure our data is always what we expect it to be. In this case, we’ll define the three data properties each of our bookmarks has. It’s important to define all your data in your schema, otherwise it won’t be available to your templates. We provide the loader property with a content loader. In this case, we’ll use the file loader that Astro provides and give it the path to our JSON. Finally, we need to export the collections variable as an object containing all the collections that we’ve defined (just bookmarks in our project). You’ll want to restart the local server by re-running npm run dev in your terminal to pick up the new data. Using the new bookmarks content collection Now that we have data, we can use it in our homepage to show the most recent bookmarks that have been added. To get the data, we need to access the content collection with the getCollection method from astro:content. Add the following code to the frontmatter for ./src/pages/index.astro . --- import Layout from '../layouts/Layout.astro'; import { getCollection } from 'astro:content'; const bookmarks = await getCollection('bookmarks'); --- This code imports the getCollection method and uses it to create a new variable that contains the data in our bookmarkscollection. The bookmarks variable is an array of data, as defined by the collection, which we can use to loop through in our template. --- import Layout from '../layouts/Layout.astro'; import { getCollection } from 'astro:content'; const bookmarks = await getCollection('bookmarks'); --- <Layout> <div class="max-w-3xl mx-auto my-10"> <h1 class="text-3xl text-center">My latest bookmarks</h1> <p class="text-xl text-center mb-5"> This is only 10 of {bookmarks.length} </p> <h2 class="text-2xl mb-3">Latest bookmarks</h2> <ul class="grid gap-4"> { bookmarks.slice(0, 10).map((item) => ( <li> <a href={item.data?.url} class="block p-6 bg-white border border-gray-200 rounded-lg shadow-sm hover:bg-gray-100 dark:bg-gray-800 dark:border-gray-700 dark:hover:bg-gray-700"> <h3 class="mb-2 text-2xl font-bold tracking-tight text-gray-900 dark:text-white"> {item.data?.pageTitle} </h3> <p class="font-normal text-gray-700 dark:text-gray-400"> {item.data?.description} </p> </a> </li> )) } </ul> </div> </Layout> This should pull the most recent 10 items from the array and display them on the homepage with some Tailwind styles. The main thing to note here is that the data structure has changed a little. The actual data for each item in our array actually resides in the data property of the item. This allows Astro to put additional data on the object without colliding with any details we provide in our database. Your project should now look something like this. Now that we have data and display, let’s get to work on our search functionality. Building search with actions and vanilla JavaScript To start, we’ll want to scaffold out a new Astro component. In our example, we’re going to use vanilla JavaScript, but if you’re familiar with React or other frameworks that Astro supports, you can opt for client Islands to build out your search. The Astro actions will work the same. Setting up the component We need to make a new component to house a bit of JavaScript and the HTML for the search field and results. Create the component in a ./src/components/Search.astro file. <form id="searchForm" class="flex mb-6 items-center max-w-sm mx-auto"> <label for="simple-search" class="sr-only">Search</label> <div class="relative w-full"> <input type="text" id="search" class="bg-gray-50 border border-gray-300 text-gray-900 text-sm rounded-lg focus:ring-blue-500 focus:border-blue-500 block w-full p-2.5 dark:bg-gray-700 dark:border-gray-600 dark:placeholder-gray-400 dark:text-white dark:focus:ring-blue-500 dark:focus:border-blue-500" placeholder="Search Bookmarks" required /> </div> <button type="submit" class="p-2.5 ms-2 text-sm font-medium text-white bg-blue-700 rounded-lg border border-blue-700 hover:bg-blue-800 focus:ring-4 focus:outline-none focus:ring-blue-300 dark:bg-blue-600 dark:hover:bg-blue-700 dark:focus:ring-blue-800"> <svg class="w-4 h-4" aria-hidden="true" xmlns="<http://www.w3.org/2000/svg>" fill="none" viewBox="0 0 20 20"> <path stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="m19 19-4-4m0-7A7 7 0 1 1 1 8a7 7 0 0 1 14 0Z"></path> </svg> <span class="sr-only">Search</span> </button> </form> <div class="grid gap-4 mb-10 hidden" id="results"> <h2 class="text-xl font-bold mb-2">Search Results</h2> </div> <script> const form = document.getElementById("searchForm"); const search = document.getElementById("search"); const results = document.getElementById("results"); form?.addEventListener("submit", async (e) => { e.preventDefault(); console.log("SEARCH WILL HAPPEN"); }); </script> The basic HTML is setting up a search form, input, and results area with IDs that we’ll use in JavaScript. The basic JavaScript finds those elements, and for the form, adds an event listener that fires when the form is submitted. The event listener is where a lot of our magic is going to happen, but for now, a console log will do to make sure everything is set up properly. Setting up an Astro Action for search In order for Actions to work, we need our project to allow for Astro to work in server or hybrid mode. These modes allow for all or some pages to be rendered in serverless functions instead of pre-generated as HTML during the build. In this project, this will be used for the Action and nothing else, so we’ll opt for hybrid mode. To be able to run Astro in this way, we need to add a server integration. Astro has integrations for most of the major cloud providers, as well as a basic Node implementation. I typically host on Netlify, so we’ll install their integration. Much like with Tailwind, we’ll use the CLI to add the package and it will build out the boilerplate we need. npx astro add netlify Once this is added, Astro is running in Hybrid mode. Most of our site is pre-generated with HTML, but when the Action gets used, it will run as a serverless function. Setting up a very basic search Action Next, we need an Astro Action to handle our search functionality. To create the action, we need to create a new file at ./src/actions/index.js. All our Actions live in this file. You can write the code for each one in separate files and import them into this file, but in this example, we only have one Action, and that feels like premature optimization. In this file, we’ll set up our search Action. Much like setting up our content collections, we’ll use a method called defineAction and give it a schema and in this case a handler. The schema will validate the data it’s getting from our JavaScript is typed correctly, and the handler will define what happens when the Action runs. import { defineAction } from "astro:actions"; import { z } from "astro:schema"; import { getCollection } from "astro:content"; export const server = { search: defineAction({ schema: z.object({ query: z.string(), }), handler: async (query) => { const bookmarks = await getCollection("bookmarks"); const results = await bookmarks.filter((bookmark) => { return bookmark.data.pageTitle.includes(query); }); return results; }, }), }; For our Action, we’ll name it search and expect a schema of an object with a single property named query which is a string. The handler function will get all of our bookmarks from the content collection and use a native JavaScript .filter() method to check if the query is included in any bookmark titles. This basic functionality is ready to test with our front-end. Using the Astro Action in the search form event When the user submits the form, we need to send the query to our new Action. Instead of figuring out where to send our fetch request, Astro gives us access to all of our server Actions with the actions object in astro:actions. This means that any Action we create is accessible from our client-side JavaScript. In our Search component, we can now import our Action directly into the JavaScript and then use the search action when the user submits the form. <script> import { actions } from "astro:actions"; const form = document.getElementById("searchForm"); const search = document.getElementById("search"); const results = document.getElementById("results"); form?.addEventListener("submit", async (e) => { e.preventDefault(); results.innerHTML = ""; const query = search.value; const { data, error } = await actions.search(query); if (error) { results.innerHTML = `<p>${error.message}</p>`; return; } // create a div for each search result data.forEach(( item ) => { const div = document.createElement("div"); div.innerHTML = ` <a href="${item.data?.url}" class="block p-6 bg-white border border-gray-200 rounded-lg shadow-sm hover:bg-gray-100 dark:bg-gray-800 dark:border-gray-700 dark:hover:bg-gray-700"> <h3 class="mb-2 text-2xl font-bold tracking-tight text-gray-900 dark:text-white"> ${item.data?.pageTitle} </h3> <p class="font-normal text-gray-700 dark:text-gray-400"> ${item.data?.description} </p> </a>`; // append the div to the results container results.appendChild(div); }); // show the results container results.classList.remove("hidden"); }); </script> When results are returned, we can now get search results! Though, they’re highly problematic. This is just a simple JavaScript filter, after all. You can search for “Favorite” and get my favorite bread recipe, but if you search for “favorite” (no caps), you’ll get an error… Not ideal. That’s why we should use a package like Fuse.js. Adding Fuse.js for fuzzy search Fuse.js is a JavaScript package that has utilities to make “fuzzy” search much easier for developers. Fuse will accept a string and based on a number of criteria (and a number of sets of data) provide responses that closely match even when the match isn’t perfect. Depending on the settings, Fuse can match “Favorite”, “favorite”, and even misspellings like “favrite” all to the right results. Is Fuse as powerful as something like Algolia or ElasticSearch? No. Is it free and pretty darned good? Absolutely! To get Fuse moving, we need to install it into our project. npm install fuse.js From there, we can use it in our Action by importing it in the file and creating a new instance of Fuse based on our bookmarks collection. import { defineAction } from "astro:actions"; import { z } from "astro:schema"; import { getCollection } from "astro:content"; import Fuse from "fuse.js"; export const server = { search: defineAction({ schema: z.object({ query: z.string(), }), handler: async (query) => { const bookmarks = await getCollection("bookmarks"); const fuse = new Fuse(bookmarks, { threshold: 0.3, keys: [ { name: "data.pageTitle", weight: 1.0 }, { name: "data.description", weight: 0.7 }, { name: "data.url", weight: 0.3 }, ], }); const results = await fuse.search(query); return results; }, }), }; In this case, we create the Fuse instance with a few options. We give it a threshold value between 0 and 1 to decide how “fuzzy” to make the search. Fuzziness is definitely something that depends on use case and the dataset. In our dataset, I’ve found 0.3 to be a great threshold. The keys array allows you to specify which data should be searched. In this case, I want all the data to be searched, but I want to allow for different weighting for each item. The title should be most important, followed by the description, and the URL should be last. This way, I can search for keywords in all these areas. Once there’s a new Fuse instance, we run fuse.search(query) to have Fuse check the data, and return an array of results. When we run this with our front-end, we find we have one more issue to tackle. The structure of the data returned is not quite what it was with our simple JavaScript. Each result now has a refIndex and an item. All our data lives on the item, so we need to destructure the item off of each returned result. To do that, adjust the front-end forEach. // create a div for each search result data.forEach(({ item }) => { const div = document.createElement("div"); div.innerHTML = ` <a href="${item.data?.url}" class="block p-6 bg-white border border-gray-200 rounded-lg shadow-sm hover:bg-gray-100 dark:bg-gray-800 dark:border-gray-700 dark:hover:bg-gray-700"> <h3 class="mb-2 text-2xl font-bold tracking-tight text-gray-900 dark:text-white"> ${item.data?.pageTitle} </h3> <p class="font-normal text-gray-700 dark:text-gray-400"> ${item.data?.description} </p> </a>`; // append the div to the results container results.appendChild(div); }); Now, we have a fully working search for our bookmarks. Next steps This just scratches the surface of what you can do with Astro Actions. For instance, we should probably add additional error handling based on the error we get back. You can also experiment with handling this at the page-level and letting there be a Search page where the Action is used as a form action and handles it all as a server request instead of with front-end JavaScript code. You could also refactor the JavaScript from the admittedly low-tech vanilla JS to something a bit more robust with React, Svelte, or Vue. One thing is for sure, Astro keeps looking at the front-end landscape and learning from the mistakes and best practices of all the other frameworks. Actions, Content Layer, and more are just the beginning for a truly compelling front-end framework. Powering Search With Astro Actions and Fuse.js originally published on CSS-Tricks, which is part of the DigitalOcean family. You should get the newsletter.

                                                                                                                                                                                                                                                                                                                                                                    Smashing Meets Accessibility

                                                                                                                                                                                                                                                                                                                                                                    • Links
                                                                                                                                                                                                                                                                                                                                                                    • accessibility

                                                                                                                                                                                                                                                                                                                                                                    The videos from Smashing Magazine's recent event on accessibility were just posted the other day. I was invited to host the panel discussion with the speakers, including a couple of personal heroes of mine, Stéphanie Walter and Sarah Fossheim. But I was just as stoked to meet Kardo Ayoub who shared his deeply personal story as a designer with a major visual impairment.

                                                                                                                                                                                                                                                                                                                                                                    Smashing Meets Accessibility originally published on CSS-Tricks, which is part of the DigitalOcean family. You should get the newsletter.

                                                                                                                                                                                                                                                                                                                                                                    The videos from Smashing Magazine’s recent event on accessibility were just posted the other day. I was invited to host the panel discussion with the speakers, including a couple of personal heroes of mine, Stéphanie Walter and Sarah Fossheim. But I was just as stoked to meet Kardo Ayoub who shared his deeply personal story as a designer with a major visual impairment. I’ll drop the video here: I’ll be the first to admit that I had to hold back my emotions as Kardo detailed what led to his impairment, the shock that came of it, and how he has beaten the odds to not only be an effective designer, but a real leader in the industry. It’s well worth watching his full presentation, which is also available on YouTube alongside the full presentations from Stéphanie and Sarah. Smashing Meets Accessibility originally published on CSS-Tricks, which is part of the DigitalOcean family. You should get the newsletter.

                                                                                                                                                                                                                                                                                                                                                                    A CSS-Only Star Rating Component and More! (Part 2)

                                                                                                                                                                                                                                                                                                                                                                    • Articles
                                                                                                                                                                                                                                                                                                                                                                    • forms
                                                                                                                                                                                                                                                                                                                                                                    • Scroll Driven Animation

                                                                                                                                                                                                                                                                                                                                                                    In this second article of a two-part series, Temani Afif demonstrates an alternative approach to creating the star rating component from the first article using experimental scroll-driven animations rather than using the border-image property.

                                                                                                                                                                                                                                                                                                                                                                    A CSS-Only Star Rating Component and More! (Part 2) originally published on CSS-Tricks, which is part of the DigitalOcean family. You should get the newsletter.

                                                                                                                                                                                                                                                                                                                                                                    In the last article, we created a CSS-only star rating component using the CSS mask and border-image properties, as well as the newly enhanced attr() function. We ended with CSS code that we can easily adjust to create component variations, including a heart rating and volume control. This second article will study a different approach that gives us more flexibility. Instead of the border-image trick we used in the first article, we will rely on scroll-driven animations! Here is the same star rating component with the new implementation. And since we’re treading in experimental territory, you’ll want to view this in Chrome 115+ while we wait for Safari and Firefox support: CodePen Embed Fallback Do you spot the difference between this and the final demo in the first article? This time, I am updating the color of the stars based on how many of them are selected — something we cannot do using the border-image trick! I highly recommend you read the first article before jumping into this second part if you missed it, as I will be referring to concepts and techniques that we explored over there. One more time: At the time of writing, only Chrome 115+ and Edge 115+ fully support the features we will be using in this article, so please use either one of those as you follow along. Why scroll-driven animations? You might be wondering why we’re talking about scroll-driven animation when there’s nothing to scroll to in the star rating component. Scrolling? Animation? It’s even more confusing when you read the MDN explainer for scroll-driven animations: It allows you to animate property values based on a progression along a scroll-based timeline instead of the default time-based document timeline. This means that you can animate an element by scrolling a scrollable element, rather than just by the passing of time. But if you keep reading you will see that we have two types of scroll-based timelines: scroll progress timelines and view progress timelines. In our case, we are going to use the second one; a view progress timeline, and here is how MDN describes it: You progress this timeline based on the change in visibility of an element (known as the subject) inside a scroller. The visibility of the subject inside the scroller is tracked as a percentage of progress — by default, the timeline is at 0% when the subject is first visible at one edge of the scroller, and 100% when it reaches the opposite edge. You can check out the CSS-Tricks almanac definition for view-timeline-name while you’re at it for another explanation. Things start to make more sense if we consider the thumb element as the subject and the input element as the scroller. After all, the thumb moves within the input area, so its visibility changes. We can track that movement as a percentage of progress and convert it to a value we can use to style the input element. We are essentially going to implement the equivalent of document.querySelector("input").value in JavaScript but with vanilla CSS! The implementation Now that we have an idea of how this works, let’s see how everything translates into code. @property --val { syntax: "<number>"; inherits: true; initial-value: 0; } input[type="range"] { --min: attr(min type(<number>)); --max: attr(max type(<number>)); timeline-scope: --val; animation: --val linear both; animation-timeline: --val; animation-range: entry 100% exit 0%; overflow: hidden; } @keyframes --val { 0% { --val: var(--max) } 100% { --val: var(--min) } } input[type="range"]::thumb { view-timeline: --val inline; } I know, this is a lot of strange syntax! But we will dissect each line and you will see that it’s not all that complex at the end of the day. The subject and the scroller We start by defining the subject, i.e. the thumb element, and for this we use the view-timeline shorthand property. From the MDN page, we can read: The view-timeline CSS shorthand property is used to define a named view progress timeline, which is progressed through based on the change in visibility of an element (known as the subject) inside a scrollable element (scroller). view-timeline is set on the subject. I think it’s self-explanatory. The view timeline name is --val and the axis is inline since we’re working along the horizontal x-axis. Next, we define the scroller, i.e. the input element, and for this, we use overflow: hidden (or overflow: auto). This part is the easiest but also the one you will forget the most so let me insist on this: don’t forget to define overflow on the scroller! I insist on this because your code will work fine without defining overflow, but the values won’t be good. The reason is that the scroller exists but will be defined by the browser (depending on your page structure and your CSS) and most of the time it’s not the one you want. So let me repeat it another time: remember the overflow property! The animation Next up, we create an animation that animates the --val variable between the input’s min and max values. Like we did in the first article, we are using the newly-enhanced attr() function to get those values. See that? The “animation” part of the scroll-driven animation, an animation we link to the view timeline we defined on the subject using animation-timeline. And to be able to animate a variable we register it using @property. Note the use of timeline-scope which is another tricky feature that’s easy to overlook. By default, named view timelines are scoped to the element where they are defined and its descendant. In our case, the input is a parent element of the thumb so it cannot access the named view timeline. To overcome this, we increase the scope using timeline-scope. Again, from MDN: timeline-scope is given the name of a timeline defined on a descendant element; this causes the scope of the timeline to be increased to the element that timeline-scope is set on and any of its descendants. In other words, that element and any of its descendant elements can now be controlled using that timeline. Never forget about this! Sometimes everything is correctly defined but nothing is working because you forget about the scope. There’s something else you might be wondering: Why are the keyframes values inverted? Why is the min is set to 100% and the max set to 0%? To understand this, let’s first take the following example where you can scroll the container horizontally to reveal a red circle inside of it. CodePen Embed Fallback Initially, the red circle is hidden on the right side. Once we start scrolling, it appears from the right side, then disappears to the left as you continue scrolling towards the right. We scroll from left to right but our actual movement is from right to left. In our case, we don’t have any scrolling since our subject (the thumb) will not overflow the scroller (the input) but the main logic is the same. The starting point is the right side and the ending point is the left side. In other words, the animation starts when the thumb is on the right side (the input’s max value) and will end when it’s on the left side (the input’s min value). The animation range The last piece of the puzzle is the following important line of code: animation-range: entry 100% exit 0%; By default, the animation starts when the subject starts to enter the scroller from the right and ends when the subject has completely exited the scroller from the left. This is not good because, as we said, the thumb will not overflow the scroller, so it will never reach the start and the end of the animation. To rectify this we use the animation-range property to make the start of the animation when the subject has completely entered the scroller from the right (entry 100%) and the end of the animation when the subject starts to exit the scroller from the left (exit 0%). To summarize, the thumb element will move within input’s area and that movement is used to control the progress of an animation that animates a variable between the input’s min and max attribute values. We have our replacement for document.querySelector("input").value in JavaScript! What’s going on with all the --val instances everywhere? Is it the same thing each time? I am deliberately using the same --val everywhere to confuse you a little and push you to try to understand what is going on. We usually use the dashed ident (--) notation to define custom properties (also called CSS variables) that we later call with var(). This is still true but that same notation can be used to name other things as well. In our examples we have three different things named --val: The variable that is animated and registered using @property. It contains the selected value and is used to style the input. The named view timeline defined by view-timeline and used by animation-timeline. The keyframes named --val and called by animation. Here is the same code written with different names for more clarity: @property --val { syntax: "<number>"; inherits: true; initial-value: 0; } input[type="range"] { --min: attr(min type(<number>)); --max: attr(max type(<number>)); timeline-scope: --timeline; animation: value_update linear both; animation-timeline: --timeline; animation-range: entry 100% exit 0%; overflow: hidden; } @keyframes value_update { 0% { --val: var(--max) } 100% { --val: var(--min) } } input[type="range"]::thumb { view-timeline: --timeine inline; } The star rating component All that we have done up to now is get the selected value of the input range — which is honestly about 90% of the work we need to do. What remains is some basic styles and code taken from what we made in the first article. If we omit the code from the previous section and the code from the previous article here is what we are left with: input[type="range"] { background: linear-gradient(90deg, hsl(calc(30 + 4 * var(--val)) 100% 56%) calc(var(--val) * 100% / var(--max)), #7b7b7b 0 ); } input[type="range"]::thumb { opacity: 0; } We make the thumb invisible and we define a gradient on the main element to color in the stars. No surprise here, but the gradient uses the same --val variable that contains the selected value to inform how much is colored in. When, for example, you select three stars, the --val variable will equal 3 and the color stop of the first color will equal 3*100%/5 , or 60%, meaning three stars are colored in. That same color is also dynamic as I am using the hsl() function where the first argument (the hue) is a function of --val as well. Here is the full demo, which you will want to open in Chrome 115+ at the time I’m writing this: CodePen Embed Fallback And guess what? This implementation works with half stars as well without the need to change the CSS. All you have to do is update the input’s attributes to work in half increments. <input type="range" min=".5" step=".5" max="5"> CodePen Embed Fallback That’s it! We have our rating star component that you can easily control by adjusting the attributes. So, should I use border-image or a scroll-driven animation? If we look past the browser support factor, I consider this version better than the border-image approach we used in the first article. The border-image version is simpler and does the job pretty well, but it’s limited in what it can do. While our goal is to create a star rating component, it’s good to be able to do more and be able to style an input range as you want. With scroll-driven animations, we have more flexibility since the idea is to first get the value of the input and then use it to style the element. I know it’s not easy to grasp but don’t worry about that. You will face scroll-driven animations more often in the future and it will become more familiar with time. This example will look easy to you in good time. Worth noting, that the code used to get the value is a generic code that you can easily reuse even if you are not going to style the input itself. Getting the value of the input is independent of styling it. Here is a demo where I am adding a tooltip to a range slider to show its value: CodePen Embed Fallback Many techniques are involved to create that demo and one of them is using scroll-driven animations to get the input value and show it inside the tooltip! Here is another demo using the same technique where different range sliders are controlling different variables on the page. CodePen Embed Fallback And why not a wavy range slider? CodePen Embed Fallback This one is a bit crazy but it illustrates how far we go with styling an input range! So, even if your goal is not to create a star rating component, there are a lot of use cases where such a technique can be really useful. Conclusion I hope you enjoyed this brief two-part series. In addition to a star rating component made with minimal code, we have explored a lot of cool and modern features, including the attr() function, CSS mask, and scroll-driven animations. It’s still early to adopt all of these features in production because of browser support, but it’s a good time to explore them and see what can be done soon using only CSS. Article series A CSS-Only Star Rating Component and More! (Part 1) A CSS-Only Star Rating Component and More! (Part 2) A CSS-Only Star Rating Component and More! (Part 2) originally published on CSS-Tricks, which is part of the DigitalOcean family. You should get the newsletter.

                                                                                                                                                                                                                                                                                                                                                                    Maybe don’t use custom properties in shorthand properties

                                                                                                                                                                                                                                                                                                                                                                    • Links
                                                                                                                                                                                                                                                                                                                                                                    • cascade
                                                                                                                                                                                                                                                                                                                                                                    • custom properties

                                                                                                                                                                                                                                                                                                                                                                    This easily qualifies as a "gotcha" in CSS and is a good reminder that the cascade doesn't know everything all at the same time. If a custom property is invalid, the cascade won't ignore it, and it gets evaluated, which invalidates the declaration.

                                                                                                                                                                                                                                                                                                                                                                    Maybe don’t use custom properties in shorthand properties originally published on CSS-Tricks, which is part of the DigitalOcean family. You should get the newsletter.

                                                                                                                                                                                                                                                                                                                                                                    Manuel Matuzović: That an invalid custom property invalidates the entire declaration isn’t surprising, but I didn’t consider it until I saw one of my declarations break. I guess it’s just good to know that, especially if you’re working a lot with custom properties. This easily qualifies as a “gotcha” in CSS and is a good reminder that the cascade doesn’t know everything all at the same time. If a custom property is invalid, the cascade won’t ignore it, and it gets evaluated, which invalidates the declaration. And if we set an invalid custom property on a shorthand property that combines several constituent properties — like how background and animation are both shorthand for a bunch of other properties — then the entire declaration becomes invalid, including all of the implied constituents. No bueno indeed. What to do, then? So, maybe don’t use custom properties in shorthand properties or use custom properties but don’t use shorthand properties. Great advice, Manuel! Maybe don’t use custom properties in shorthand properties originally published on CSS-Tricks, which is part of the DigitalOcean family. You should get the newsletter.

                                                                                                                                                                                                                                                                                                                                                                    Grouping Selection List Items Together With CSS Grid

                                                                                                                                                                                                                                                                                                                                                                    • Articles
                                                                                                                                                                                                                                                                                                                                                                    • forms
                                                                                                                                                                                                                                                                                                                                                                    • layout

                                                                                                                                                                                                                                                                                                                                                                    Preethi demonstrates how to make a user interface to group selected items using CSS Grid using two different methods: the auto-fill keyword for stable layouts and the span keyword for flexible arrangements.

                                                                                                                                                                                                                                                                                                                                                                    Grouping Selection List Items Together With CSS Grid originally published on CSS-Tricks, which is part of the DigitalOcean family. You should get the newsletter.

                                                                                                                                                                                                                                                                                                                                                                    Grouping selected items is a design choice often employed to help users quickly grasp which items are selected and unselected. For instance, checked-off items move up the list in to-do lists, allowing users to focus on the remaining tasks when they revisit the list. We’ll design a UI that follows a similar grouping pattern. Instead of simply rearranging the list of selected items, we’ll also lay them out horizontally using CSS Grid. This further distinguishes between the selected and unselected items. We’ll explore two approaches for this. One involves using auto-fill, which is suitable when the selected items don’t exceed the grid container’s boundaries, ensuring a stable layout. In contrast, CSS Grid’s span keyword provides another approach that offers greater flexibility. The HTML is the same for both methods: <ul> <li> <label> <input type="checkbox" /> <div class=icon>🍱</div> <div class=text>Bento</div> </label> </li> <li> <label> <input type="checkbox" /> <div class=icon>🍡</div> <div class=text>Dangos</div> </label> </li> <!-- more list items --> </ul> The markup consists of an unordered list (<ul>). However, we don’t necessarily have to use <ul> and <li> elements since the layout of the items will be determined by the CSS grid properties. Note that I am using an implicit <label> around the <input> elements mostly as a way to avoid needing an extra wrapper around things, but that explicit labels are generally better supported by assistive technologies. Method 1: Using auto-fill CodePen Embed Fallback ul { width: 250px; display: grid; gap: 14px 10px; grid-template-columns: repeat(auto-fill, 40px); justify-content: center; /* etc. */ } The <ul> element, which contains the items, has a display: grid style rule, turning it into a grid container. It also has gaps of 14px and 10px between its grid rows and columns. The grid content is justified (inline alignment) to center. The grid-template-columns property specifies how column tracks will be sized in the grid. Initially, all items will be in a single column. However, when items are selected, they will be moved to the first row, and each selected item will be in its own column. The key part of this declaration is the auto-fill value. The auto-fill value is added where the repeat count goes in the repeat() function. This ensures the columns repeat, with each column’s track sizing being the given size in repeat() (40px in our example), that will fit inside the grid container’s boundaries. For now, let’s make sure that the list items are positioned in a single column: li { width: inherit; grid-column: 1; /* Equivalent to: grid-column-start: 1; grid-column-end: auto; */ /* etc. */ } When an item is checked, that is when an <li> element :has() a :checked checkbox, we’re selecting that. And when we do, the <li> is given a grid-area that puts it in the first row, and its column will be auto-placed within the grid in the first row as per the value of the grid-template-columns property of the grid container (<ul>). This causes the selected items to group at the top of the list and be arranged horizontally: li { width: inherit; grid-column: 1; /* etc. */ &:has(:checked) { grid-area: 1; /* Equivalent to: grid-row-start: 1; grid-column-start: auto; grid-row-end: auto; grid-column-end: auto; */ width: 40px; /* etc. */ } /* etc. */ } And that gives us our final result! Let’s compare that with the second method I want to show you. Method 2: Using the span keyword CodePen Embed Fallback We won’t be needing the grid-template-columns property now. Here’s the new <ul> style ruleset: ul { width: 250px; display: grid; gap: 14px 10px; justify-content: center; justify-items: center; /* etc. */ } The inclusion of justify-items will help with the alignment of grid items as we’ll see in a moment. Here are the updated styles for the <li> element: li { width: inherit; grid-column: 1 / span 6; /* Equivalent to: grid-column-start: 1; grid-column-end: span 6; */ /* etc. */ } As before, each item is placed in the first column, but now they also span six column tracks (since there are six items). This ensures that when multiple columns appear in the grid, as items are selected, the following unselected items remain in a single column under the selected items — now the unselected items span across multiple column tracks. The justify-items: center declaration will keep the items aligned to the center. li { width: inherit; grid-column: 1 / span 6; /* etc. */ &:has(:checked) { grid-area: 1; width: 120px; /* etc. */ } /* etc. */ } The width of the selected items has been increased from the previous example, so the layout of the selection UI can be viewed for when the selected items overflow the container. Selection order The order of selected and unselected items will remain the same as the source order. If the on-screen order needs to match the user’s selection, dynamically assign an incremental order value to the items as they are selected. onload = ()=>{ let i=1; document.querySelectorAll('input').forEach((input)=>{ input.addEventListener("click", () => { input.parentElement.parentElement.style.order = input.checked ? i++ : (i--, 0); }); }); } CodePen Embed Fallback Wrapping up CSS Grid helps make both approaches very flexible without a ton of configuration. By using auto-fill to place items on either axis (rows or columns), the selected items can be easily grouped within the grid container without disturbing the layout of the unselected items in the same container, for as long as the selected items don’t overflow the container. If they do overflow the container, using the span approach helps maintain the layout irrespective of how long the group of selected items gets in a given axis. Some design alternatives for the UI are grouping the selected items at the end of the list, or swapping the horizontal and vertical structure. Grouping Selection List Items Together With CSS Grid originally published on CSS-Tricks, which is part of the DigitalOcean family. You should get the newsletter.

                                                                                                                                                                                                                                                                                                                                                                    Functions in CSS?!

                                                                                                                                                                                                                                                                                                                                                                    • Notes
                                                                                                                                                                                                                                                                                                                                                                    • functions

                                                                                                                                                                                                                                                                                                                                                                    Arguments?! Return values?! What's crazier, you can use functions right now in Chrome Canary! So, after reading and playing around, here are my key insights on what you need to know about CSS Functions.

                                                                                                                                                                                                                                                                                                                                                                    Functions in CSS?! originally published on CSS-Tricks, which is part of the DigitalOcean family. You should get the newsletter.

                                                                                                                                                                                                                                                                                                                                                                    A much-needed disclaimer: You (kinda) can use functions now! I know, it isn’t the most pleasant feeling to finish reading about a new feature just for the author to say “And we’ll hopefully see it in a couple of years”. Luckily, right now you can use an (incomplete) version of CSS functions in Chrome Canary behind an experimental flag, although who knows when we’ll get to use them in a production environment. Arguments, defaults, and returns! I was drinking coffee when I read the news on Chrome prototyping functions in CSS and… I didn’t spit it or anything. I was excited, but thought “functions” in CSS would be just like mixins in Sass — you know, patterns for establishing reusable patterns. That’s cool but is really more or less syntactic sugar for writing less CSS. But I looked at the example snippet a little more closely and that’s when the coffee nearly came shooting out my mouth. From Bramus in Bluesky Arguments?! Return values?! That’s worth spitting my coffee out for! I had to learn more about them, and luckily, the spec is clearly written, which you can find right here. What’s crazier, you can use functions right now in Chrome Canary! So, after reading and playing around, here are my key insights on what you need to know about CSS Functions. What exactly is a function in CSS? I like this definition from the spec: Custom functions allow authors the same power as custom properties, but parameterized They are used in the same places you would use a custom property, but functions return different things depending on the argument we pass. The syntax for the most basic function is the @function at-rule, followed by the name of the function as a <dashed-ident> + () @function --dashed-border() { /* ... */ } A function without arguments is like a custom property, so meh… To make them functional we can pass arguments inside the parenthesis, also as <dashed-ident>s @function --dashed-border(--color) { /* ... */ } We can use the result descriptor to return something based on our argument: @function --dashed-border(--color) { result: 2px dashed var(--color); } div { border: --dashed-border(blue); /* 2px dashed blue */ } We can even use defaults! Just write a colon (:) followed by the default value for that argument. @function --dashed-border(--color: red) { result: 2px dashed var(--color); } div { border: --dashed-border(); /* 2px dashed red */ } CodePen Embed Fallback This reminds me of Adam Argyle’s experiment on a functional CSS concept. Functions can have type-checking Functions can have type-checking for arguments and return values, which will be useful whenever we want to interpolate a value just like we do with variables created with @property, and once we have inline conditionals, to make different calculations depending on the argument type. To add argument types, we pass a syntax component. That is the type enclosed in angle brackets, where color is <color> and length is <length>, just to name a couple. There are also syntax multipliers like plus (+) to accept a space-separated list of that type. @function --custom-spacing(--a <length>) { /* ... */ } /* e.g. 10px */ @function --custom-background(--b <color>) { /* ... */ } /* e.g. hsl(50%, 30% 50%) */ @function --custom-margin(--c <length>+) { /* ... */ } /* e.g. 10px 2rem 20px */ If instead, we want to define the type of the return value, we can write the returns keyword followed by the syntax component: @function --progression(--current, --total) returns <percentage> { result: calc(var(--current) / var(--total) * 100%); } Just a little exception for types: if we want to accept more than one type using the syntax combinator (|), we’ll have to enclose the types in a type() wrapper function: @function --wideness(--d type(<number> | <percentage>)) { /* ... */ } Functions can have list arguments While it doesn’t currently seem to work in Canary, we’ll be able in the future to take lists as arguments by enclosing them inside curly braces. So, this example from the spec passes a list of values like {1px, 7px, 2px} and gets its maximum to perform a sum. @function --max-plus-x(--list, --x) { result: calc(max(var(--list)) + var(--x)); } div { width: --max-plus-x({ 1px, 7px, 2px }, 3px); /* 10px */ } I wonder then, will it be possible to select a specific element from a list? And also define how long should the list should be? Say we want to only accept lists that contain four elements, then select each individually to perform some calculation and return it. Many questions here! Early returns aren’t possible That’s correct, early returns aren’t possible. This isn’t something defined in the spec that hasn’t been prototyped, but something that simply won’t be allowed. So, if we have two returns, one enclosed early behind a @media or @supports at-rule and one outside at the end, the last result will always be returned: @function --suitable-font-size() { @media (width > 1000px) { result: 20px; } result: 16px; /* This always returns 16px */ } We have to change the order of the returns, leaving the conditional result for last. This doesn’t make a lot of sense in other programming languages, where the function ends after returning something, but there is a reason the C in CSS stands for Cascade: this order allows the conditional result to override the last result which is very CSS-y is nature: @function --suitable-font-size() { result: 16px; @media (width > 1000px) { result: 20px; } } Imagining the possibilities Here I wanted everyone to chip in and write about the new things we could make using functions. So the team here at CSS-Tricks put our heads together and thought about some use cases for functions. Some are little helper functions we’ll sprinkle a lot throughout our CSS, while others open new possibilities. Remember, all of these examples should be viewed in Chrome Canary until support expands to other browsers. Here’s a basic helper function from Geoff that sets fluid type: @function --fluid-type(--font-min, --font-max) { result: clamp(var(--font-min), 4vw + 1rem, var(--font-max)); } h2 { font-size: --fluid-type(24px, 36px); } CodePen Embed Fallback This one is from Ryan, who is setting the width with an intrinsic container function — notice the default arguments. @function --intrinsic-container(--inline-margin: 1rem, --max-width: 60ch) { result: min(100% - var(--inline-margin), var(--max-width)); } CodePen Embed Fallback And check out this second helper function from Ryan to create grid layouts: @function --layout-sidebar(--sidebar-width: 10ch) { result: 1fr; @media (width > 640px) { result: fit-content(var(--sidebar-width)) minmax(min(50vw, 30ch), 1fr); } } This is one of those snippets I’m always grabbing from Steph Eckles’ smolcss site, and having a function would be so much easier. Actually, most of the snippets on Steph’s site would be awesome functions. CodePen Embed Fallback This one is from moi. When I made that demo using tan(atan2()) to create viewport transitions, I used a helper property called --wideness to get the screen width as a decimal between 0 to 1. At that moment, I wished for a function form of --wideness. As I described it back then: You pass a lower and upper bound as pixels, and it will return a 0 to 1 value depending on how wide the screen is. So for example, if the screen is 800px, wideness(400px, 1200px) would return 0.5 since it’s the middle point I thought I would never see it, but now I can make it myself! Using that wideness function, I can move an element through its offset-path as the screen goes from 400px to 800px: .marker { offset-path: path("M 5 5 m -4, 0 a 4,4 0 1,0 8,0 a 4,4 0 1,0 -8,0"); /* Circular Orbit */ offset-distance: calc(--wideness(400, 800) * 100%); /* moves the element when the screen goes from 400px to 800px */ } CodePen Embed Fallback What’s missing? According to Chrome’s issue on CSS Functions, we are in a super early stage since we cannot: …use local variables. Although I tried them and they seem to work. …use recursive functions (they crash!), …list arguments, …update a function and let the appropriate styles change, …use @function in cascade layers, or in the CSS Object Model (CSSOM), …use “the Iverson bracket functions … so any @media queries or similar will need to be made using helper custom properties (on :root or similar).” After reading what on earth an Iverson bracket is, I understood that we currently can’t have a return value behind a @media or @support rule. For example, this snippet from the spec shouldn’t work: @function --suitable-font-size() { result: 16px; @media (width > 1000px) { result: 20px; } } Although, upon testing, it seems like it’s supported now. Still, we can use a provisional custom property and return it at the end if it isn’t working for you: @function --suitable-font-size() { --size: 16px; @media (width > 600px) { --size: 20px; } result: var(--size); } CodePen Embed Fallback What about mixins? Soon, they’ll be here. According to the spec: At this time, this specification only defines custom functions, which operate at the level of CSS values. It is expected that it will define “mixins” later, which are functions that operate at the style rule level. In conclusion… I say it with confidence: functions will bring an enormous change to CSS, not in the sense that we’ll write it any differently — we won’t use functions to center a <div>, but they will simplify hack-ish CSS and open a lot of new possibilities. There’ll be a time when our cyborg children ask us from their education pods, “Is it true you guys didn’t have functions in CSS?” And we’ll answer “No, Zeta-5 ∀umina™, we didn’t” while shedding a tear. And that will blow their ZetaPentium© Gen 31 Brain chips. That is if CSS lasts long enough, but in the meantime, I am happy to change my site’s font with a function. Functions in CSS?! originally published on CSS-Tricks, which is part of the DigitalOcean family. You should get the newsletter.

                                                                                                                                                                                                                                                                                                                                                                    A CSS-Only Star Rating Component and More! (Part 1)

                                                                                                                                                                                                                                                                                                                                                                    • Articles
                                                                                                                                                                                                                                                                                                                                                                    • attributes
                                                                                                                                                                                                                                                                                                                                                                    • borders
                                                                                                                                                                                                                                                                                                                                                                    • forms

                                                                                                                                                                                                                                                                                                                                                                    In this article, you'll learn how to make a full-on star rating component out of nothing but a single input element and vanilla CSS.

                                                                                                                                                                                                                                                                                                                                                                    A CSS-Only Star Rating Component and More! (Part 1) originally published on CSS-Tricks, which is part of the DigitalOcean family. You should get the newsletter.

                                                                                                                                                                                                                                                                                                                                                                    Creating a star rating component is a classic exercise in web development. It has been done and re-done many times using different techniques. We usually need a small amount of JavaScript to pull it together, but what about a CSS-only implementation? Yes, it is possible! Here is a demo of a CSS-only star rating component. You can click to update the rating. CodePen Embed Fallback Cool, right? In addition to being CSS-only, the HTML code is nothing but a single element: <input type="range" min="1" max="5"> An input range element is the perfect candidate here since it allows a user to select a numeric value between two boundaries (the min and max). Our goal is to style that native element and transform it into a star rating component without additional markup or any script! We will also create more components at the end, so follow along. Note: This article will only focus on the CSS part. While I try my best to consider UI, UX, and accessibility aspects, my component is not perfect. It may have some drawbacks (bugs, accessibility issues, etc), so please use it with caution. The <input> element You probably know it but styling native elements such as inputs is a bit tricky due to all the default browser styles and also the different internal structures. If, for example, you inspect the code of an input range you will see a different HTML between Chrome (or Safari, or Edge) and Firefox. Luckily, we have some common parts that I will rely on. I will target two different elements: the main element (the input itself) and the thumb element (the one you slide with your mouse to update the value). Our CSS will mainly look like this: input[type="range"] { /* styling the main element */ } input[type="range" i]::-webkit-slider-thumb { /* styling the thumb for Chrome, Safari and Edge */ } input[type="range"]::-moz-range-thumb { /* styling the thumb for Firefox */ } The only drawback is that we need to repeat the styles of the thumb element twice. Don’t try to do the following: input[type="range" i]::-webkit-slider-thumb, input[type="range"]::-moz-range-thumb { /* styling the thumb */ } This doesn’t work because the whole selector is invalid. Chrome & Co. don’t understand the ::-moz-* part and Firefox doesn’t understand the ::-webkit-* part. For the sake of simplicity, I will use the following selector for this article: input[type="range"]::thumb { /* styling the thumb */ } But the demo contains the real selectors with the duplicated styles. Enough introduction, let’s start coding! Styling the main element (the star shape) We start by defining the size: input[type="range"] { --s: 100px; /* control the size*/ height: var(--s); aspect-ratio: 5; appearance: none; /* remove the default browser styles */ } If we consider that each star is placed within a square area, then for a 5-star rating we need a width equal to five times the height, hence the use of aspect-ratio: 5. CodePen Embed Fallback That 5 value is also the value defined as the max attribute for the input element. <input type="range" min="1" max="5"> So, we can rely on the newly enhanced attr() function (Chrome-only at the moment) to read that value instead of manually defining it! input[type="range"] { --s: 100px; /* control the size*/ height: var(--s); aspect-ratio: attr(max type(<number>)); appearance: none; /* remove the default browser styles */ } Now you can control the number of stars by simply adjusting the max attribute. This is great because the max attribute is also used by the browser internally, so updating that value will control our implementation as well as the browser’s behavior. This enhanced version of attr() is only available in Chrome for now so all my demos will contain a fallback to help with unsupported browsers. The next step is to use a CSS mask to create the stars. We need the shape to repeat five times (or more depending on the max value) so the mask size should be equal to var(--s) var(--s) or var(--s) 100% or simply var(--s) since by default the height will be equal to 100%. input[type="range"] { --s: 100px; /* control the size*/ height: var(--s); aspect-ratio: attr(max type(<number>)); appearance: none; /* remove the default browser styles */ mask-image: /* ... */; mask-size: var(--s); } What about the mask-image property you might ask? I think it’s no surprise that I tell you it will require a few gradients, but it could also be SVG instead. This article is about creating a star-rating component but I would like to keep the star part kind of generic so you can easily replace it with any shape you want. That’s why I say “and more” in the title of this post. We will see later how using the same code structure we can get a variety of different variations. Here is a demo showing two different implementations for the star. One is using gradients and the other is using an SVG. CodePen Embed Fallback In this case, the SVG implementation looks cleaner and the code is also shorter but keep both approaches in your back pocket because a gradient implementation can do a better job in some situations. Styling the thumb (the selected value) Let’s now focus on the thumb element. Take the last demo then click the stars and notice the position of the thumb. CodePen Embed Fallback The good thing is that the thumb is always within the area of a given star for all the values (from min to max), but the position is different for each star. It would be good if the position is always the same, regardless of the value. Ideally, the thumb should always be at the center of the stars for consistency. Here is a figure to illustrate the position and how to update it. The lines are the position of the thumb for each value. On the left, we have the default positions where the thumb goes from the left edge to the right edge of the main element. On the right, if we restrict the position of the thumb to a smaller area by adding some spaces on the sides, we get much better alignment. That space is equal to half the size of one star, or var(--s)/2. We can use padding for this: input[type="range"] { --s: 100px; /* control the size */ height: var(--s); aspect-ratio: attr(max type(<number>)); padding-inline: calc(var(--s) / 2); box-sizing: border-box; appearance: none; /* remove the default browser styles */ mask-image: ...; mask-size: var(--s); } CodePen Embed Fallback It’s better but not perfect because I am not accounting for the thumb size, which means we don’t have true centering. It’s not an issue because I will make the size of the thumb very small with a width equal to 1px. input[type="range"]::thumb { width: 1px; height: var(--s); appearance: none; /* remove the default browser styles */ } CodePen Embed Fallback The thumb is now a thin line placed at the center of the stars. I am using a red color to highlight the position but in reality, I don’t need any color because it will be transparent. You may think we are still far from the final result but we are almost done! One property is missing to complete the puzzle: border-image. The border-image property allows us to draw decorations outside an element thanks to its outset feature. For this reason, I made the thumb small and transparent. The coloration will be done using border-image. I will use a gradient with two solid colors as the source: linear-gradient(90deg, gold 50%, grey 0); And we write the following: border-image: linear-gradient(90deg, gold 50%, grey 0) fill 0 // 0 100px; The above means that we extend the area of the border-image from each side of the element by 100px and the gradient will fill that area. In other words, each color of the gradient will cover half of that area, which is 100px. CodePen Embed Fallback Do you see the logic? We created a kind of overflowing coloration on each side of the thumb — a coloration that will logically follow the thumb so each time you click a star it slides into place! Now instead of 100px let’s use a very big value: CodePen Embed Fallback We are getting close! The coloration is filling all the stars but we don’t want it to be in the middle but rather across the entire selected star. For this, we update the gradient a bit and instead of using 50%, we use 50% + var(--s)/2. We add an offset equal to half the width of a star which means the first color will take more space and our star rating component is perfect! CodePen Embed Fallback We can still optimize the code a little where instead of defining a height for the thumb, we keep it 0 and we consider the vertical outset of border-image to spread the coloration. input[type="range"]::thumb{ width: 1px; border-image: linear-gradient(90deg, gold calc(50% + var(--s) / 2), grey 0) fill 0 // var(--s) 500px; appearance: none; } We can also write the gradient differently using a conic gradient instead: input[type="range"]::thumb{ width: 1px; border-image: conic-gradient(at calc(50% + var(--s) / 2), grey 50%, gold 0) fill 0 // var(--s) 500px; appearance: none; } I know that the syntax of border-image is not easy to grasp and I went a bit fast with the explanation. But I have a very detailed article over at Smashing Magazine where I dissect that property with a lot of examples that I invite you to read for a deeper dive into how the property works. The full code of our component is this: <input type="range" min="1" max="5"> input[type="range"] { --s: 100px; /* control the size*/ height: var(--s); aspect-ratio: attr(max type(<number>)); padding-inline: calc(var(--s) / 2); box-sizing: border-box; appearance: none; mask-image: /* ... */; /* either an SVG or gradients */ mask-size: var(--s); } input[type="range"]::thumb { width: 1px; border-image: conic-gradient(at calc(50% + var(--s) / 2), grey 50%, gold 0) fill 0//var(--s) 500px; appearance: none; } That’s all! A few lines of CSS code and we have a nice rating star component! Half-Star Rating What about having a granularity of half a star as a rating? It’s something common and we can do it with the previous code by making a few adjustments. First, we update the input element to increment in half steps instead of full steps: <input type="range" min=".5" step=".5" max="5"> By default, the step is equal to 1 but we can update it to .5 (or any value) then we update the min value to .5 as well. On the CSS side, we change the padding from var(--s)/2 to var(--s)/4, and we do the same for the offset inside the gradient. input[type="range"] { --s: 100px; /* control the size*/ height: var(--s); aspect-ratio: attr(max type(<number>)); padding-inline: calc(var(--s) / 4); box-sizing: border-box; appearance: none; mask-image: ...; /* either SVG or gradients */ mask-size: var(--s); } input[type="range"]::thumb{ width: 1px; border-image: conic-gradient(at calc(50% + var(--s) / 4),grey 50%, gold 0) fill 0 // var(--s) 500px; appearance: none; } The difference between the two implementations is a factor of one-half which is also the step value. That means we can use attr() and create a generic code that works for both cases. input[type="range"] { --s: 100px; /* control the size*/ --_s: calc(attr(step type(<number>),1) * var(--s) / 2); height: var(--s); aspect-ratio: attr(max type(<number>)); padding-inline: var(--_s); box-sizing: border-box; appearance: none; mask-image: ...; /* either an SVG or gradients */ mask-size: var(--s); } input[type="range"]::thumb{ width: 1px; border-image: conic-gradient(at calc(50% + var(--_s)),gold 50%,grey 0) fill 0//var(--s) 500px; appearance: none; } Here is a demo where modifying the step is all that you need to do to control the granularity. Don’t forget that you can also control the number of stars using the max attribute. CodePen Embed Fallback Using the keyboard to adjust the rating As you may know, we can adjust the value of an input range slider using a keyboard, so we can control the rating using the keyboard as well. That’s a good thing but there is a caveat. Due to the use of the mask property, we no longer have the default outline that indicates keyboard focus which is an accessibility concern for those who rely on keyboard input. For a better user experience and to make the component more accessible, it’s good to display an outline on focus. The easiest solution is to add an extra wrapper: <span> <input type="range" min="1" max="5"> </span> That will have an outline when the input inside has focus: span:has(:focus-visible) { outline: 2px solid; } Try to use your keyboard in the below example to adjust both ratings: CodePen Embed Fallback Another idea is to consider a more complex mask configuration that keeps a small area around the element visible to show the outline: mask: /* ... */ 0/var(--s), conic-gradient(from 90deg at 2px 2px,#0000 25%,#000 0) 0 0/calc(100% - 2px) calc(100% - 2px); I prefer using this last method because it maintains the single-element implementation but maybe your HTML structure allows you to add focus on an upper element and you can keep the mask configuration simple. It totally depends! CodePen Embed Fallback More examples! As I said earlier, what we are making is more than a star rating component. You can easily update the mask value to use any shape you want. Here is an example where I am using an SVG of a heart instead of a star. CodePen Embed Fallback Why not butterflies? CodePen Embed Fallback This time I am using a PNG image as a mask. If you are not comfortable using SVG or gradients you can use a transparent image instead. As long as you have an SVG, a PNG, or gradients, there is no limit on what you can do with this as far as shapes go. We can go even further into the customization and create a volume control component like below: CodePen Embed Fallback I am not repeating a specific shape in that last example, but am using a complex mask configuration to create a signal shape. Conclusion We started with a star rating component and ended with a bunch of cool examples. The title could have been “How to style an input range element” because this is what we did. We upgraded a native component without any script or extra markup, and with only a few lines of CSS. What about you? Can you think about another fancy component using the same code structure? Share your example in the comment section! Article series A CSS-Only Star Rating Component and More! (Part 1) A CSS-Only Star Rating Component and More! (Part 2) A CSS-Only Star Rating Component and More! (Part 1) originally published on CSS-Tricks, which is part of the DigitalOcean family. You should get the newsletter.

                                                                                                                                                                                                                                                                                                                                                                    WWDC25: June 9-13, 2025

                                                                                                                                                                                                                                                                                                                                                                      Join the worldwide developer community online for a week of technology and creativity.

                                                                                                                                                                                                                                                                                                                                                                      Be there for the reveal of the latest Apple tools, frameworks, and features. Learn to elevate your apps and games through video sessions hosted by Apple engineers and designers. Engage with Apple experts in labs and connect with the worldwide developer community. All online and at no cost.

                                                                                                                                                                                                                                                                                                                                                                      Learn more about WWDC25

                                                                                                                                                                                                                                                                                                                                                                      Assassin’s Creed Shadows comes to Mac

                                                                                                                                                                                                                                                                                                                                                                        It’s an ice-cold late winter’s morning in Canada, but the offices of Ubisoft Quebec are ablaze with excitement.

                                                                                                                                                                                                                                                                                                                                                                        The Ubisoft team is preparing the release of Assassin’s Creed Shadows, the 14th main entry in the series and an evolution for the franchise in nearly every detail. It’s set in feudal 16th-century Japan, a rich and elegant period that’s been long sought-after by fans and Ubisoft team members alike. It introduces a pair of fierce protagonists: Yasuke, a powerful warrior of African origin, and Naoe, an agile Shinobi assassin, both brought to life with attention to historical accuracy. Its world feels alive with an ever-changing dynamism that’s apparent in everything from the shifting weather to the rotating seasons to the magical interplay of light and shadow.

                                                                                                                                                                                                                                                                                                                                                                        And what’s more, it’s set to release on Mac the same day it arrives on PCs and consoles.

                                                                                                                                                                                                                                                                                                                                                                        “It’s been a longtime dream to bring the game to Mac,” says Ubisoft executive producer Marc-Alexis Côté, who debuted the game on Mac during the WWDC24 Keynote. “It’s incredible that I can now open a MacBook Pro and get this level of immersion.” Shadows will also be coming later to iPad with M-series chips.

                                                                                                                                                                                                                                                                                                                                                                        Naoe, one of the game’s two protagonists, is an agile assassin who’s at her best when striking from the shadows.

                                                                                                                                                                                                                                                                                                                                                                        Today marks one of the first times that the gaming community will get its hands on Shadows, and to celebrate the occasion, the Ubisoft offices — a mix of cozy chalet-worthy reclaimed wood and wide-open windows that afford a view of snowy Quebec City rooftops — have been reskinned with an Assassin’s Creed theme, including a display that emphasizes the heft of Yasuke’s weapons, especially an imposing-looking 13-pound model of the character’s sword. (On this day, the display is hosted by associate game director Simon Lemay-Comtois, who appears quite capable of wielding it.)

                                                                                                                                                                                                                                                                                                                                                                        Pre-order Assassin's Creed Shadows from the Mac App Store

                                                                                                                                                                                                                                                                                                                                                                        Côté calls Shadows his team’s “most ambitious” game. In crafting the game’s expansive world, Ubisoft’s development team took advantage of an array of advanced Mac technologies: Metal 3 (working in concert with Ubisoft’s next-generation Anvil engine), Apple silicon, and a mix of HDR support and real-time ray tracing on Macs with M3 and M4 that Côté says was “transformative” in creating the game’s immersion.

                                                                                                                                                                                                                                                                                                                                                                        It’s been a longtime dream to bring the game to Mac.

                                                                                                                                                                                                                                                                                                                                                                        Marc-Alexis Côté, Ubisoft executive producer

                                                                                                                                                                                                                                                                                                                                                                        “Seeing those millions of lines of code work natively on a Mac was a feeling that’s hard to describe,” Côté says. “When you look at the game’s performance, the curve Apple is on with successive improvements to the M-series chips year after year, and the way the game looks on an HDR screen, you’re like, ‘Is this real?’”

                                                                                                                                                                                                                                                                                                                                                                        Assassin’s Creed Shadows is a balance of the technical and creative. For the former, associate technical director Mathieu Belanger says the capabilities of Mac laid the groundwork for technical success. “The architecture of the hardware is so well done, thanks in part to the unified memory between the GPU and CPU. That made us think the future is bright for gaming on the platform. So many things about doing this on Mac were great right out of the box.”

                                                                                                                                                                                                                                                                                                                                                                        Naoe’s counterpart, Yasuke, prefers the use of brute force.

                                                                                                                                                                                                                                                                                                                                                                        On the creative side, Ubisoft creative director Jonathan Dumont focused on a different opportunity. “The important thing was: Does this feel right? Is it what we want to send to players? And the answer was yes.”

                                                                                                                                                                                                                                                                                                                                                                        The creative team’s goal was nothing short of “making this world feel alive,” says Martin Bedard, a 20-year Ubisoft veteran who served as the game’s technology director (and is very good at playing as Naoe). “You’re put into a moment that really existed,” he says. “This story is your playground.”

                                                                                                                                                                                                                                                                                                                                                                        There are also fluffy kittens. We’ll get to those.

                                                                                                                                                                                                                                                                                                                                                                        The ever-changing seasons lend an incredible variety to the game’s environments.

                                                                                                                                                                                                                                                                                                                                                                        And there’s tremendous power behind the beauty, because the game’s biomes, seasons, weather, and lighting are all dynamic creations. The sunset hour bathes the mountains in soft purple light; the sun’s rays float in through leaves and temple roofs. Pretty much every room has a candle in it, which means the light is always changing. “Look at the clouds here,” says Bedard, pointing at the screen. “That’s not a rendering. These are all fluid-based cloud simulations.”

                                                                                                                                                                                                                                                                                                                                                                        “Japan feels like it’s 80 percent trees and mountains,” says Dumont. “If you’re building this world without the rain, and the winds, and the mountains, it doesn’t feel right.”

                                                                                                                                                                                                                                                                                                                                                                        Wherever you are, wherever you go, everything is beautiful and alive.

                                                                                                                                                                                                                                                                                                                                                                        Mathieu Belanger, associate technical director

                                                                                                                                                                                                                                                                                                                                                                        And those winds? “We developed a lot of features that were barely possible before, and one of them was a full simulation of the wind, not just an animation,” says Belanger. “We even built a humidity simulation that gathers clouds together.” For the in-game seasons, Ubisoft developed an engine that depicted houses, markets, and temples, in ever-changing conditions. “This was all done along the way over the past four years,” he says.

                                                                                                                                                                                                                                                                                                                                                                        To pursue historical accuracy, Dumont and the creative team visited Japan to study every detail, including big-picture details (like town maps) to very specific ones (like the varnish that would have been applied to 16th-century wood). It wasn’t always a slam dunk, says Côté: In one visit, their Japanese hosts recommended a revision to the light splashing against the mountains. “We want to get all those little details right,” he says. (A “full-immersion version,” entirely in Japanese with English subtitles, is available.)

                                                                                                                                                                                                                                                                                                                                                                        To recreate the world of 16th-century Japan, the Ubisoft creative visited Japan to study every detail.

                                                                                                                                                                                                                                                                                                                                                                        Ubisoft’s decision to split the protagonist into two distinct characters with different identities, skill sets, origin stories, and class backgrounds came early in the process. (“That was a fun day,” laughs Belanger.) Ubisoft team members emphasize that choosing between Naoe and Yasuke is a matter of personal preference — lethal subtlety vs. brute force. Players can switch between characters at any time, and, as you might suspect, the pair grows stronger together as the story goes on. Much of Naoe’s advantage comes from her ability to linger in the game’s shadows — not just behind big buildings, but wherever the scene creates a space for her to hide. “The masterclass is clearing out a board without being spotted once,” says Bedard.

                                                                                                                                                                                                                                                                                                                                                                        (The Hideout is) peaceful. You can say, ‘I feel like putting some trees down, seeing what I collected, upgrading my buildings, and petting the cats.’

                                                                                                                                                                                                                                                                                                                                                                        Jonathan Dumont, Ubisoft creative director

                                                                                                                                                                                                                                                                                                                                                                        Which brings us to the Hideout, Naoe and Yasuke’s home base and a bucolic rural village that acts as a zen-infused respite from the ferocity of battle. “It’s a place that welcomes you back,” says Dumont. It’s eminently customizable, both from a game-progression standpoint but also in terms of aesthetics. Where the battle scenes are a frenzy of bruising combat or stealth attacks, the Hideout is a refuge for supplies, artwork, found objects, and even a furry menagerie of cats, dogs, deer, and other calming influences. “There are progressions, of course,” says Dumont, “but it’s peaceful. You can say, ‘I feel like putting some trees down, seeing what I collected, upgrading my buildings, and petting the cats.”

                                                                                                                                                                                                                                                                                                                                                                        “The kittens were a P1 feature,” laughs associate game director Dany St-Laurent.

                                                                                                                                                                                                                                                                                                                                                                        Yasuke prepares to face off against an opponent in what will likely be a fruitful battle.

                                                                                                                                                                                                                                                                                                                                                                        Yet for all those big numbers, Dumont says the game boils down to something much simpler. “I just think the characters work super-well together,” he says. “It’s an open-world game, yes. But at its core, it features two characters you’ll like. And the game is really about following their journey, connecting with them, exploring their unique mysteries, and seeing how they flow together. And I think the way in which they join forces is one of the best moments in the franchise.”

                                                                                                                                                                                                                                                                                                                                                                        And if the Ubisoft team has its way, there will be plenty more moments to come. “I think the game will scale for years to come on the Mac platform,” says Côté. “Games can be more and more immersive with each new hardware release. We’re trying to create something here where more people can come with day-one games on the Mac, because I think it’s a beautiful platform.”

                                                                                                                                                                                                                                                                                                                                                                        Pre-order Assassin's Creed Shadows from the Mac App Store

                                                                                                                                                                                                                                                                                                                                                                        Hello Developer: March 2025

                                                                                                                                                                                                                                                                                                                                                                          In this edition: An incredible AAA game comes to Mac. Plus, the latest on International Women’s Day activities, WeChat, and more.

                                                                                                                                                                                                                                                                                                                                                                          Read the full article

                                                                                                                                                                                                                                                                                                                                                                          Apple Developer is now on WeChat

                                                                                                                                                                                                                                                                                                                                                                            Check out the official Apple Developer WeChat account to find news, announcements, and upcoming activities for the developer community.

                                                                                                                                                                                                                                                                                                                                                                            Learn more in Simplified Chinese

                                                                                                                                                                                                                                                                                                                                                                            Get ready with the latest beta releases

                                                                                                                                                                                                                                                                                                                                                                              The beta versions of iOS 18.4, iPadOS 18.4, macOS 15.4, tvOS 18.4, visionOS 2.4, and watchOS 11.4 are now available. Get your apps ready by confirming they work as expected on these releases. And to take advantage of the advancements in the latest SDKs, make sure to build and test with Xcode 16.3.

                                                                                                                                                                                                                                                                                                                                                                              As previewed last year, iOS 18.4 and iPadOS 18.4 include support for default translation apps for all users worldwide, and default navigation apps for EU users.

                                                                                                                                                                                                                                                                                                                                                                              Beginning April 24, 2025, apps uploaded to App Store Connect must be built with Xcode 16 or later using an SDK for iOS 18, iPadOS 18, tvOS 18, visionOS 2, or watchOS 11.

                                                                                                                                                                                                                                                                                                                                                                              View downloads and release notes

                                                                                                                                                                                                                                                                                                                                                                              New requirement for apps on the App Store in the European Union

                                                                                                                                                                                                                                                                                                                                                                                As of today, apps without trader status have been removed from the App Store in the European Union (EU) until trader status is provided and verified by Apple.

                                                                                                                                                                                                                                                                                                                                                                                Account Holders or Admins in the Apple Developer Program will need to enter this status in App Store Connect to comply with the Digital Services Act.

                                                                                                                                                                                                                                                                                                                                                                                Learn what a trader is and how to enter your status

                                                                                                                                                                                                                                                                                                                                                                                New features for APNs token authentication are now available

                                                                                                                                                                                                                                                                                                                                                                                  You can now take advantage of upgraded security options when creating new token authentication keys for the Apple Push Notification service (APNs).

                                                                                                                                                                                                                                                                                                                                                                                  Team-scoped keys enable you to restrict your token authentication keys to either development or production environments, providing an additional layer of security and ensuring that keys are used only in their intended environments.

                                                                                                                                                                                                                                                                                                                                                                                  Topic-specific keys provide more granular control by enabling you to associate each key with a specific bundle ID, allowing for more streamlined and organized key management. This is particularly beneficial for large organizations that manage multiple apps across different teams.

                                                                                                                                                                                                                                                                                                                                                                                  Your existing keys will continue to work for all push topics and environments. At this time, you don’t have to update your keys unless you want to take advantage of the new capabilities.

                                                                                                                                                                                                                                                                                                                                                                                  For detailed instructions on how to secure your communications with APNs, read Establishing a token-based connection to APNs.

                                                                                                                                                                                                                                                                                                                                                                                  Upcoming changes to offers and trials for subscriptions in South Korea

                                                                                                                                                                                                                                                                                                                                                                                    Starting February 14, 2025, new regulatory requirements in South Korea will apply to all apps with offers and trials for auto-renewing subscriptions.

                                                                                                                                                                                                                                                                                                                                                                                    To comply, if you offer trials or offers for auto-renewing subscriptions to your app or game, additional consent must be obtained for your trial or offer after the initial transaction. The App Store will help to get consent by informing the affected subscribers with an email, push notification, and in-app price consent sheet, and asking your subscribers to agree to the new price.

                                                                                                                                                                                                                                                                                                                                                                                    This additional consent must be obtained from customers within 30 days from the payment or conversion date for:

                                                                                                                                                                                                                                                                                                                                                                                    • Free to paid trials
                                                                                                                                                                                                                                                                                                                                                                                    • Discounted subscription offers to standard-price subscriptions

                                                                                                                                                                                                                                                                                                                                                                                    Apps that do not offer a free trial or discounted offer before a subscription converts to the regular price are not affected.

                                                                                                                                                                                                                                                                                                                                                                                    Learn more about this regulation

                                                                                                                                                                                                                                                                                                                                                                                    Tax and price updates for apps, In-App Purchases, and subscriptions

                                                                                                                                                                                                                                                                                                                                                                                      The App Store is designed to make it easy to sell your digital goods and services globally, with support for 44 currencies across 175 storefronts.

                                                                                                                                                                                                                                                                                                                                                                                      From time to time, we may need to adjust prices or your proceeds due to changes in tax regulations or foreign exchange rates. These adjustments are made using publicly available exchange rate information from financial data providers to help make sure prices for apps and In-App Purchases stay consistent across all storefronts.

                                                                                                                                                                                                                                                                                                                                                                                      Tax and pricing updates for February

                                                                                                                                                                                                                                                                                                                                                                                      As of February 6:

                                                                                                                                                                                                                                                                                                                                                                                      Your proceeds from the sale of eligible apps and In‑App Purchases have been modified in:

                                                                                                                                                                                                                                                                                                                                                                                      • Azerbaijan: value-added tax (VAT) introduction of 18%
                                                                                                                                                                                                                                                                                                                                                                                      • Peru: VAT introduction of 18%
                                                                                                                                                                                                                                                                                                                                                                                      • Slovakia: Standard VAT rate increase from 20% to 23%
                                                                                                                                                                                                                                                                                                                                                                                      • Slovakia: Reduced VAT rate introduction of 5% for ebooks
                                                                                                                                                                                                                                                                                                                                                                                      • Estonia: Reduced VAT rate increase from 5% to 9% for news publications, magazines, and other periodicals
                                                                                                                                                                                                                                                                                                                                                                                      • Finland: Reduced VAT rate increase from 10% to 14% for ebooks

                                                                                                                                                                                                                                                                                                                                                                                      Exhibit B of the Paid Applications Agreement has been updated to indicate that Apple collects and remits applicable taxes in Azerbaijan and Peru.¹

                                                                                                                                                                                                                                                                                                                                                                                      As of February 24:

                                                                                                                                                                                                                                                                                                                                                                                      Pricing for apps and In-App Purchases will be updated for the Azerbaijan and Peru storefronts if you haven’t selected one of these as the base for your app or In‑App Purchase.² These updates also consider VAT introductions listed in the tax updates section above.

                                                                                                                                                                                                                                                                                                                                                                                      If you’ve selected the Azerbaijan or Peru storefront as the base for your app or In-App Purchase, prices won’t change. On other storefronts, prices will be updated to maintain equalization with your chosen base price.

                                                                                                                                                                                                                                                                                                                                                                                      Prices won’t change in any region if your In‑App Purchase is an auto‑renewable subscription. Prices also won’t change on the storefronts where you manually manage prices instead of using the automated equalized prices.

                                                                                                                                                                                                                                                                                                                                                                                      The Pricing and Availability section of Apps has been updated in App Store Connect to display these upcoming price changes. As always, you can change the prices of your apps, In‑App Purchases, and auto‑renewable subscriptions at any time.

                                                                                                                                                                                                                                                                                                                                                                                      Learn more about managing your prices

                                                                                                                                                                                                                                                                                                                                                                                      View or edit upcoming price changes

                                                                                                                                                                                                                                                                                                                                                                                      Edit your app’s base country or region

                                                                                                                                                                                                                                                                                                                                                                                      Pricing and availability start times by country or region

                                                                                                                                                                                                                                                                                                                                                                                      Set a price for an In-App Purchase

                                                                                                                                                                                                                                                                                                                                                                                      Beginning April 1:

                                                                                                                                                                                                                                                                                                                                                                                      As a result of last year’s change in Japan’s tax regulations, Apple (through iTunes K.K. in Japan) is now designated as a Specified Platform Operator by the Japan tax authority. All paid apps and In-App Purchases, (including game items, such as coins) sold by non-Japan-based developers on the App Store in Japan will be subject to the platform tax regime. Apple will collect and remit a 10% Japanese consumption tax (JCT) to the National Tax Agency JAPAN on such transactions at the time of purchase. Your proceeds will be adjusted accordingly.

                                                                                                                                                                                                                                                                                                                                                                                      Please note any prepaid payment instruments (such as coins) sold prior to April 1, 2025, will not be subject to platform taxation, and the relevant JCT compliance should continue to be managed by the developer.

                                                                                                                                                                                                                                                                                                                                                                                      For specific information on how the JCT affects in-game items, see Question 7 in the Tax Agency of Japan’s Q&A about Platform Taxation of Consumption Tax.

                                                                                                                                                                                                                                                                                                                                                                                      Learn more about your proceeds

                                                                                                                                                                                                                                                                                                                                                                                      View payments and proceeds

                                                                                                                                                                                                                                                                                                                                                                                      Download financial reports

                                                                                                                                                                                                                                                                                                                                                                                      ¹ Translations of the updated agreement are available on the Apple Developer website today.

                                                                                                                                                                                                                                                                                                                                                                                      ² Excludes auto-renewable subscriptions.

                                                                                                                                                                                                                                                                                                                                                                                      Game distribution on the App Store in Vietnam

                                                                                                                                                                                                                                                                                                                                                                                        The Vietnamese Ministry of Information and Communications (MIC) requires games to be licensed to remain available on the App Store in Vietnam. To learn more and apply for a game license, review the regulations.

                                                                                                                                                                                                                                                                                                                                                                                        Once you have obtained your license:

                                                                                                                                                                                                                                                                                                                                                                                        • Sign in to App Store Connect.
                                                                                                                                                                                                                                                                                                                                                                                        • Enter the license number and the associated URL in the description section of your game’s product page.
                                                                                                                                                                                                                                                                                                                                                                                        • Note that you only need to provide this information for the App Store localization displayed on the Vietnam storefront.
                                                                                                                                                                                                                                                                                                                                                                                        • Submit an update to App Review.

                                                                                                                                                                                                                                                                                                                                                                                        If you have questions on how to comply with these requirements, please contact the Authority of Broadcasting and Electronic Information (ABEI) under the Vietnamese Ministry of Information and Communications.

                                                                                                                                                                                                                                                                                                                                                                                        View the full law

                                                                                                                                                                                                                                                                                                                                                                                        Hello Developer: February 2025

                                                                                                                                                                                                                                                                                                                                                                                          In this edition: The latest on developer activities, the Swift Student Challenge, the team behind Bears Gratitude, and more.

                                                                                                                                                                                                                                                                                                                                                                                          Read the full article

                                                                                                                                                                                                                                                                                                                                                                                          The good news bears: Inside the adorably unorthodox design of Bears Gratitude

                                                                                                                                                                                                                                                                                                                                                                                            Here’s the story of how a few little bears led their creators right to an Apple Design Award.

                                                                                                                                                                                                                                                                                                                                                                                            Bears Gratitude is a warm and welcoming title developed by the Australian husband-and-wife team of Isuru Wanasinghe and Nayomi Hettiarachchi.

                                                                                                                                                                                                                                                                                                                                                                                            Journaling apps just don’t get much cuter: Through prompts like “Today isn’t over yet,” “I’m literally a new me,” and “Compliment someone,” the Swift-built app and its simple hand-drawn mascots encourage people to get in the habit of celebrating accomplishments, fostering introspection, and building gratitude. “And gratitude doesn’t have to be about big moments like birthdays or anniversaries,” says Wanasinghe. “It can be as simple as having a hot cup of coffee in the morning.”

                                                                                                                                                                                                                                                                                                                                                                                            ADA FACT SHEET

                                                                                                                                                                                                                                                                                                                                                                                            Bears Gratitude
                                                                                                                                                                                                                                                                                                                                                                                            • Winner: Delight and Fun
                                                                                                                                                                                                                                                                                                                                                                                            • Available on: iOS, iPadOS, macOS
                                                                                                                                                                                                                                                                                                                                                                                            • Team size: 2

                                                                                                                                                                                                                                                                                                                                                                                            Download Bears Gratitude from the App Store

                                                                                                                                                                                                                                                                                                                                                                                            Wanasinghe is a longtime programmer who’s run an afterschool tutoring center in Sydney, Australia, for nearly a decade. But the true spark for Bears Gratitude and its predecessor, Bears Countdown, came from Hettiarachchi, a Sri Lankan-born illustrator who concentrated on her drawing hobby during the Covid-19 lockdown.

                                                                                                                                                                                                                                                                                                                                                                                            Wanasinghe is more direct. “The art is the heart of everything we do,” he says.

                                                                                                                                                                                                                                                                                                                                                                                            Bears Gratitude was developed by the Australian husband-and-wife team of Isuru Wanasinghe and Nayomi Hettiarachchi.

                                                                                                                                                                                                                                                                                                                                                                                            In fact, the art is the whole reason the app exists. As the pandemic months and drawings stacked up, Hettiarachchi and Wanasinghe found themselves increasingly attached to her cartoon creations, enough that they began to consider how to share them with the world. The usual social media routes beckoned, but given Wanasinghe’s background, the idea of an app offered a stronger pull.

                                                                                                                                                                                                                                                                                                                                                                                            “In many cases, you get an idea, put together a design, and then do the actual development,” he says. “In our case, it’s the other way around. The art drives everything.”

                                                                                                                                                                                                                                                                                                                                                                                            The art is the heart of everything we do.

                                                                                                                                                                                                                                                                                                                                                                                            Isuru Wanasinghe, Bears Gratitude cofounder

                                                                                                                                                                                                                                                                                                                                                                                            With hundreds of drawings at their disposal, the couple began thinking about the kinds of apps that could host them. Their first release was Bears Countdown, which employed the drawings to help people look ahead to birthdays, vacations, and other marquee moments. Countdown was never intended to be a mass-market app; the pair didn’t even check its launch stats on App Store Connect. “We’d have been excited to have 100 people enjoy what Nayomi had drawn,” says Wanasinghe. “That’s where our heads were at.”

                                                                                                                                                                                                                                                                                                                                                                                            But Countdown caught on with a few influencers and become enough of a success that the pair began thinking of next steps. “We thought, well, we’ve given people a way to look forward,” says Wanasinghe. “What about reflecting on the day you just had?’”

                                                                                                                                                                                                                                                                                                                                                                                            Hettiarachchi’s art samples get a close inspection from one of her trusted associates.

                                                                                                                                                                                                                                                                                                                                                                                            Gratitude keeps the cuddly cast from Countdown, but otherwise the app is an entirely different beast. It was also designed in what Wanasinghe says was a deliberately unusual manner. “Our design approach was almost bizarrely linear,” says Wanasinghe. “We purposely didn’t map out the app. We designed it in the same order that users experience it.”

                                                                                                                                                                                                                                                                                                                                                                                            Other unorthodox decisions followed, including the absence of a sign-in screen. “We wanted people to go straight into the experience and start writing,” he says. The home-screen journaling prompts are presented via cards that users flip through by tapping left and right. “It’s definitely a nonstandard UX,” says Wanasinghe, “but we found over and over again that the first thing users did was flip through the cards.”

                                                                                                                                                                                                                                                                                                                                                                                            Our design approach was almost bizarrely linear. We purposely didn’t map out the app. We designed it in the same order that users experience it.

                                                                                                                                                                                                                                                                                                                                                                                            Isuru Wanasinghe, Bears Gratitude cofounder

                                                                                                                                                                                                                                                                                                                                                                                            Another twist: The app’s prompts are written in the voice of the user, which Wanasinghe says was done to emphasize the personal nature of the app. “We wrote the app as if we were the only ones using it, which made it more relatable,” he says.

                                                                                                                                                                                                                                                                                                                                                                                            Then there are the bears, which serve not only as a distinguishing hook in a busy field, but also as a design anchor for its creators. “We’re always thinking: ‘Instead of trying to set our app apart, how do we make it ours?’ We use apps all the time, and we know how they behave. But here we tried to detach ourselves from all that, think of it as a blank canvas, and ask, ‘What do we want this experience to be?’”

                                                                                                                                                                                                                                                                                                                                                                                            Early design sketches for Bears Gratitude show the collection of swipe-able prompt cards.

                                                                                                                                                                                                                                                                                                                                                                                            Bears Gratitude isn’t a mindfulness app — Wanasinghe is careful to clarify that neither he nor Hettiarachchi are therapists or mental health professionals. “All we know about are the trials and tribulations of life,” he says.

                                                                                                                                                                                                                                                                                                                                                                                            But those trials and tribulations have reached a greater world. “People have said, ‘This is just something I visit every day that brings me comfort,’” says Wanasinghe. “We’re so grateful this is the way we chose to share the art. We’re plugged into people’s lives in a meaningful way.”

                                                                                                                                                                                                                                                                                                                                                                                            Meet the 2024 Apple Design Award winners

                                                                                                                                                                                                                                                                                                                                                                                            Behind the Design is a series that explores design practices and philosophies from finalists and winners of the Apple Design Awards. In each story, we go behind the screens with the developers and designers of these award-winning apps and games to discover how they brought their remarkable creations to life.

                                                                                                                                                                                                                                                                                                                                                                                            Apply for the Swift Student Challenge now through February 23

                                                                                                                                                                                                                                                                                                                                                                                              Submissions for the Swift Student Challenge 2025 are now open through February 23. You have three more weeks to design, test, refine, and submit your app playground for consideration to be named one of 350 winners.

                                                                                                                                                                                                                                                                                                                                                                                              What to know:

                                                                                                                                                                                                                                                                                                                                                                                              • The Challenge is free to enter — you just need access to an iPad or Mac with Swift Playground or Xcode.
                                                                                                                                                                                                                                                                                                                                                                                              • The best app ideas are personal — let your passion shine through your work.
                                                                                                                                                                                                                                                                                                                                                                                              • No formal coding experience required — the Challenge is open to students of all levels.
                                                                                                                                                                                                                                                                                                                                                                                              • Your app playground doesn’t need to be intricate — it should be experienced within 3 minutes or less.

                                                                                                                                                                                                                                                                                                                                                                                              Where to start:

                                                                                                                                                                                                                                                                                                                                                                                              Learn more about the Challenge

                                                                                                                                                                                                                                                                                                                                                                                              Introducing the Advanced Commerce API

                                                                                                                                                                                                                                                                                                                                                                                                The App Store facilitates billions of transactions annually to help developers grow their businesses and provide a world-class customer experience. To further support developers’ evolving business models — such as exceptionally large content catalogs, creator experiences, and subscriptions with optional add-ons — we’re introducing the Advanced Commerce API.

                                                                                                                                                                                                                                                                                                                                                                                                Developers can apply to use the Advanced Commerce API to support eligible App Store business models and more flexibly manage their In-App Purchases within their app. These purchases leverage the power of the trusted App Store commerce system, including end-to-end payment processing, tax support, customer service, and more, so developers can focus on providing great app experiences.

                                                                                                                                                                                                                                                                                                                                                                                                Learn about eligibility requirements and how to apply

                                                                                                                                                                                                                                                                                                                                                                                                Apps without trader status will be removed from the App Store in the EU

                                                                                                                                                                                                                                                                                                                                                                                                  Starting February 17, 2025: Due to the European Union’s Digital Services Act, apps without trader status will be removed from the App Store in the European Union until trader status is provided and verified, if necessary.

                                                                                                                                                                                                                                                                                                                                                                                                  As a reminder, Account Holders or Admins in the Apple Developer Program need to enter trader status in App Store Connect for apps on the App Store in the European Union in order to comply with the Digital Services Act.

                                                                                                                                                                                                                                                                                                                                                                                                  Learn what a trader is and how to enter your status

                                                                                                                                                                                                                                                                                                                                                                                                  Reminder: Upcoming Changes to the App Store Receipt Signing Intermediate Certificate

                                                                                                                                                                                                                                                                                                                                                                                                    As part of ongoing efforts to improve security and privacy on Apple platforms, the App Store receipt signing intermediate certificate is being updated to use the SHA-256 cryptographic algorithm. This certificate is used to sign App Store receipts, which are the proof of purchase for apps and In-App Purchases.

                                                                                                                                                                                                                                                                                                                                                                                                    This update is being completed in multiple phases and some existing apps on the App Store may be impacted by the next update, depending on how they verify receipts.

                                                                                                                                                                                                                                                                                                                                                                                                    Starting January 24, 2025, if your app performs on-device receipt validation and doesn’t support the SHA-256 algorithm, your app will fail to validate the receipt. If your app prevents customers from accessing the app or premium content when receipt validation fails, your customers may lose access to their content.

                                                                                                                                                                                                                                                                                                                                                                                                    If your app performs on-device receipt validation, update your app to support certificates that use the SHA-256 algorithm; alternatively, use the AppTransaction and Transaction APIs to verify App Store transactions.

                                                                                                                                                                                                                                                                                                                                                                                                    For more details, view TN3138: Handling App Store receipt signing certificate changes.

                                                                                                                                                                                                                                                                                                                                                                                                    Algorithm changes to server connections for Apple Pay on the Web

                                                                                                                                                                                                                                                                                                                                                                                                      Starting next month, Apple will change the supported algorithms that secure server connections for Apple Pay on the Web. In order to maintain uninterrupted service, you’ll need to ensure that your production servers support one or more of the designated six ciphers before February 4, 2025.

                                                                                                                                                                                                                                                                                                                                                                                                      These algorithm changes will affect any secure connection you’ve established as part of your Apple Pay integration, including the following touchpoints:

                                                                                                                                                                                                                                                                                                                                                                                                      Hello Developer: January 2025

                                                                                                                                                                                                                                                                                                                                                                                                        In the first edition of the new year: Bring SwiftUI to your app in Cupertino, get ready for the Swift Student Challenge, meet the team behind Oko, and more.

                                                                                                                                                                                                                                                                                                                                                                                                        Read the full article

                                                                                                                                                                                                                                                                                                                                                                                                        Walk this way: How Oko leverages AI to make street crossings more accessible

                                                                                                                                                                                                                                                                                                                                                                                                          Oko is a testament to the power of simplicity.

                                                                                                                                                                                                                                                                                                                                                                                                          The 2024 Apple Design Award winner for Inclusivity and 2024 App Store Award winner for Cultural Impact leverages Artificial Intelligence to help blind or low-vision people navigate pedestrian walkways by alerting them to the state of signals — “Walk,” “Don’t Walk,” and the like — through haptic, audio, and visual feedback. The app instantly affords more confidence to its users. Its bare-bones UI masks a powerful blend of visual and AI tools under the hood. And it’s an especially impressive achievement for a team that had no iOS or Swift development experience before launch.

                                                                                                                                                                                                                                                                                                                                                                                                          “The biggest feedback we get is, ‘It’s so simple, there’s nothing complex about it,’ and that’s great to hear,” says Vincent Janssen, one of Oko’s three Belgium-based founders. “But we designed it that way because that’s what we knew how to do. It just happened to also be the right thing.”

                                                                                                                                                                                                                                                                                                                                                                                                          ADA FACT SHEET

                                                                                                                                                                                                                                                                                                                                                                                                          From left: Willem Van de Mierop, Michiel Janssen, and Vincent Janssen are the three cofounders of Oko. The app’s name means “eye.”

                                                                                                                                                                                                                                                                                                                                                                                                          Oko
                                                                                                                                                                                                                                                                                                                                                                                                          • Winner: Inclusivity
                                                                                                                                                                                                                                                                                                                                                                                                          • Team: AYES BV
                                                                                                                                                                                                                                                                                                                                                                                                          • Available on: iPhone
                                                                                                                                                                                                                                                                                                                                                                                                          • Team size: 6
                                                                                                                                                                                                                                                                                                                                                                                                          • Previous accolades: 2024 App Store Award winner for Cultural Impact; App Store Editors’ Choice

                                                                                                                                                                                                                                                                                                                                                                                                          Learn more about Oko

                                                                                                                                                                                                                                                                                                                                                                                                          Download Oko from the App Store

                                                                                                                                                                                                                                                                                                                                                                                                          For Janssen and his cofounders, brother Michiel and longtime friend Willem Van de Mierop, Oko — the name translates to “eye” — was a passion project that came about during the pandemic. All three studied computer science with a concentration in AI, and had spent years working in their hometown of Antwerp. But by the beginning of 2021, the trio felt restless. “We all had full-time jobs,” says Janssen, “but the weekends were pretty boring.” Yet they knew their experience couldn’t compare to that of a longtime friend with low vision, who Janssen noticed was feeling more affected as the autumn and winter months went on.

                                                                                                                                                                                                                                                                                                                                                                                                          “We really started to notice that he was feeling isolated more than others,” says Janssen. “Here in Belgium, we were allowed to go for walks, but you had to be alone or with your household. That meant he couldn’t go with a volunteer or guide. As AI engineers, that got us thinking, ‘Well, there are all these stories about autonomous vehicles. Could we come up with a similar system of images or videos that would help people find their way around public spaces?’”

                                                                                                                                                                                                                                                                                                                                                                                                          I had maybe opened Xcode three times a few years before, but otherwise none of us had any iOS or Swift experience.

                                                                                                                                                                                                                                                                                                                                                                                                          Vincent Janssen, Oko founder

                                                                                                                                                                                                                                                                                                                                                                                                          The trio began building a prototype that consisted of a microcomputer, 3D-printed materials, and a small portable speaker borrowed from the Janssen brothers’ father. Today, Janssen calls it “hacky hardware,” something akin to a small computer with a camera. But it allowed the team and their friend — now their primary tester — to walk the idea around and poke at the technology’s potential. Could AI recognize the state of a pedestrian signal? How far away could it detect a Don’t Walk sign? How would it perform in rain or wind or snow? There was just one way to know. “We went out for long walks,” says Janssen.

                                                                                                                                                                                                                                                                                                                                                                                                          And while the AI and hardware performed well in their road tests, issues arose around the hardware’s size and usability, and the team begin to realize that software offered a better solution. The fact that none of the three had the slightest experience building iOS apps was simply a hurdle to clear. “I had maybe opened Xcode three times a few years before,” says Janssen, “but otherwise none of us had any iOS or Swift experience.”

                                                                                                                                                                                                                                                                                                                                                                                                          Oko helps people navigate pedestrian walkways through interactive maps and audio, visual, and haptic feedback.

                                                                                                                                                                                                                                                                                                                                                                                                          So that summer, the team pivoted to software, quitting their full-time jobs and throwing themselves into learning Swift through tutorials, videos, and trusty web searches. The core idea crystallized quickly: Build a simple app that relied on Camera, the Maps SDK, and a powerful AI algorithm that could help people get around town. “Today, it’s a little more complex, but in the beginning the app basically opened up a camera feed and a Core ML model to process the images,” says Janssen, noting that the original model was brought over from Python. “Luckily, the tools made the conversion really smooth.” (Oko’s AI models run locally on device.)

                                                                                                                                                                                                                                                                                                                                                                                                          With the software taking shape, more field testing was needed. The team reached out to accessibility-oriented organizations throughout Belgium, drafting a team of 100 or so testers to “codevelop the app,” says Janssen. Among the initial feedback: Though Oko was originally designed to be used in landscape mode, pretty much everyone preferred holding their phones in portrait mode. “I had the same experience, to be honest,” said Janssen, “but that meant we needed to redesign the whole thing.”

                                                                                                                                                                                                                                                                                                                                                                                                          The Oko team navigates through prototypes at a review session in their hometown of Antwerp, Belgium.

                                                                                                                                                                                                                                                                                                                                                                                                          Other changes included amending the audio feedback to more closely mimic existing real-world sounds, and addressing requests to add more visual feedback. The experience amounted to getting a real-world education about accessibility on the fly. “We found ourselves learning about VoiceOver and haptic feedback very quickly,” says Janssen.

                                                                                                                                                                                                                                                                                                                                                                                                          Still, the project went remarkably fast — Oko launched on the App Store in December 2021, not even a year after the trio conceived of it. “It took a little while to do things, like make sure the UI wasn’t blocked, especially since we didn’t fully understand the code we wrote in Swift,” laughs Janssen, “but in the end, the app was doing what it needed to do.”

                                                                                                                                                                                                                                                                                                                                                                                                          We found ourselves learning about VoiceOver and haptic feedback.

                                                                                                                                                                                                                                                                                                                                                                                                          Vincent Janssen, Oko founder

                                                                                                                                                                                                                                                                                                                                                                                                          The accessibility community took notice. And in the following months, the Oko team continued expanding its reach — Michiel Janssen and Van de Mierop traveled to the U.S. to meet with accessibility organizations and get firsthand experience with American street traffic and pedestrian patterns. But even as the app expanded, the team retained its focus on simplicity. In fact, Janssen says, they explored and eventually jettisoned some expansion ideas — including one designed to help people find and board public transportation — that made the app feel a little too complex.

                                                                                                                                                                                                                                                                                                                                                                                                          Today, the Oko team numbers 6, including a fleet of developers who handle more advanced Swift matters. “About a year after we launched, we got feedback about extra features and speed improvements, and needed to find people who were better at Swift than we are,” laughs Janssen. At the same time, the original trio is now learning about business, marketing, and expansion.

                                                                                                                                                                                                                                                                                                                                                                                                          At its core, Oko remains a sparkling example of a simple app that completes its task well. “It’s still a work in progress, and we’re learning every day,” says Janssen. In other words, there are many roads yet to cross.

                                                                                                                                                                                                                                                                                                                                                                                                          Meet the 2024 Apple Design Award winners

                                                                                                                                                                                                                                                                                                                                                                                                          Behind the Design is a series that explores design practices and philosophies from finalists and winners of the Apple Design Awards. In each story, we go behind the screens with the developers and designers of these award-winning apps and games to discover how they brought their remarkable creations to life.

                                                                                                                                                                                                                                                                                                                                                                                                          Get ready with the latest beta releases

                                                                                                                                                                                                                                                                                                                                                                                                            The beta versions of iOS 18.3, iPadOS 18.3, macOS 15.3, tvOS 18.3, visionOS 2.3, and watchOS 11.3 are now available. Get your apps ready by confirming they work as expected on these releases. And to take advantage of the advancements in the latest SDKs, make sure to build and test with Xcode 16.2.

                                                                                                                                                                                                                                                                                                                                                                                                            View downloads and release notes

                                                                                                                                                                                                                                                                                                                                                                                                            Learn about testing a beta OS

                                                                                                                                                                                                                                                                                                                                                                                                            Learn about sending feedback

                                                                                                                                                                                                                                                                                                                                                                                                            App Store Award winners announced

                                                                                                                                                                                                                                                                                                                                                                                                              Join us in celebrating the outstanding work of these developers from around the world.

                                                                                                                                                                                                                                                                                                                                                                                                              Meet the winners

                                                                                                                                                                                                                                                                                                                                                                                                              Updated Apple Developer Program License Agreement now available

                                                                                                                                                                                                                                                                                                                                                                                                                Attachment 2 of the Apple Developer Program License Agreement has been amended to specify requirements for use of the In-App Purchase API. Please review the changes and accept the updated terms in your account.

                                                                                                                                                                                                                                                                                                                                                                                                                View the full terms and conditions

                                                                                                                                                                                                                                                                                                                                                                                                                Translations of the updated agreement will be available on the Apple Developer website within one month.

                                                                                                                                                                                                                                                                                                                                                                                                                Hello Developer: December 2024

                                                                                                                                                                                                                                                                                                                                                                                                                  In this edition: The year in sessions, activities, apps, and games.

                                                                                                                                                                                                                                                                                                                                                                                                                  Read the full article

                                                                                                                                                                                                                                                                                                                                                                                                                  Get your apps and games ready for the holidays

                                                                                                                                                                                                                                                                                                                                                                                                                    The busiest season on the App Store is almost here. Make sure your apps and games are up to date and ready.

                                                                                                                                                                                                                                                                                                                                                                                                                    App Review will continue to accept submissions throughout the holiday season. Please plan to submit time-sensitive submissions early, as we anticipate high volume and reviews may take longer to complete from December 20-26.

                                                                                                                                                                                                                                                                                                                                                                                                                    Learn more about submitting to the App Store

                                                                                                                                                                                                                                                                                                                                                                                                                    App Store Award finalists announced

                                                                                                                                                                                                                                                                                                                                                                                                                      Every year, the App Store Awards celebrate exceptional apps and games that improve people's lives while showcasing the highest levels of technical innovation, user experience, design, and positive cultural impact. This year, the App Store Editorial team is proud to recognize over 40 outstanding finalists. Winners will be announced in the coming weeks.

                                                                                                                                                                                                                                                                                                                                                                                                                      Learn about the finalists

                                                                                                                                                                                                                                                                                                                                                                                                                      Price and tax updates for apps, In-App Purchases, and subscriptions

                                                                                                                                                                                                                                                                                                                                                                                                                        The App Store is designed to make it easy to sell your digital goods and services globally, with support for 44 currencies across 175 storefronts.

                                                                                                                                                                                                                                                                                                                                                                                                                        From time to time, we may need to adjust prices or your proceeds due to changes in tax regulations or foreign exchange rates. These adjustments are made using publicly available exchange rate information from financial data providers to help make sure prices for apps and In-App Purchases stay consistent across all storefronts.

                                                                                                                                                                                                                                                                                                                                                                                                                        Tax updates as of October:

                                                                                                                                                                                                                                                                                                                                                                                                                        Your proceeds from the sale of eligible apps and In‑App Purchases have been increased in:

                                                                                                                                                                                                                                                                                                                                                                                                                        • Nepal: Apple no longer remits Nepal value-added tax (VAT) for local developers and proceeds were increased accordingly.
                                                                                                                                                                                                                                                                                                                                                                                                                        • Kazakhstan: Apple no longer remits Kazakstan VAT for local developers and proceeds were increased accordingly.
                                                                                                                                                                                                                                                                                                                                                                                                                        • Madeira: Decrease of the Madeira VAT rate from 5% to 4% for news publications, magazines and other periodicals, books, and audiobooks.

                                                                                                                                                                                                                                                                                                                                                                                                                        Exhibit B of the Paid Applications Agreement has been updated to indicate that Apple will not remit VAT in Nepal and Kazakhstan for local developers.

                                                                                                                                                                                                                                                                                                                                                                                                                        Learn more about your proceeds

                                                                                                                                                                                                                                                                                                                                                                                                                        View payments and proceeds

                                                                                                                                                                                                                                                                                                                                                                                                                        Download financial reports

                                                                                                                                                                                                                                                                                                                                                                                                                        Price updates as of December 2:

                                                                                                                                                                                                                                                                                                                                                                                                                        • Pricing for apps and In-App Purchases will be updated for the Japan and Türkiye storefronts if you haven’t selected one of these as the base for your app or In‑App Purchases.

                                                                                                                                                                                                                                                                                                                                                                                                                        If you’ve selected the Japan or Türkiye storefront as the base for your app or In-App Purchase, prices won’t change. On other storefronts, prices will be updated to maintain equalization with your chosen base price.

                                                                                                                                                                                                                                                                                                                                                                                                                        Prices won’t change in any region if your In‑App Purchase is an auto‑renewable subscription and won’t change on the storefronts where you manually manage prices instead of using the automated equalized prices.

                                                                                                                                                                                                                                                                                                                                                                                                                        The Pricing and Availability section of Apps has been updated in App Store Connect to display these upcoming price changes. As always, you can change the prices of your apps, In‑App Purchases, and auto‑renewable subscriptions at any time.

                                                                                                                                                                                                                                                                                                                                                                                                                        Learn more about managing your prices

                                                                                                                                                                                                                                                                                                                                                                                                                        View or edit upcoming price changes

                                                                                                                                                                                                                                                                                                                                                                                                                        Edit your app’s base country or region

                                                                                                                                                                                                                                                                                                                                                                                                                        Pricing and availability start times by country or region

                                                                                                                                                                                                                                                                                                                                                                                                                        Set a price for an In-App Purchase

                                                                                                                                                                                                                                                                                                                                                                                                                        Enhancements to the App Store featuring process

                                                                                                                                                                                                                                                                                                                                                                                                                          Share your app or game’s upcoming content and enhancements for App Store featuring consideration with new Featuring Nominations in App Store Connect. Submit a nomination to tell our team about a new launch, in-app content, or added functionality. If you’re featured in select placements on the Today tab, you’ll also receive a notification via the App Store Connect app.

                                                                                                                                                                                                                                                                                                                                                                                                                          In addition, you can promote your app or game’s biggest moments — such as an app launch, new version, or select featuring placements on the App Store — with readymade marketing assets. Use the App Store Connect app to generate Apple-designed assets and share them to your social media channels. Include the provided link alongside your assets so people can easily download your app or game on the App Store.

                                                                                                                                                                                                                                                                                                                                                                                                                          Learn more about getting featured

                                                                                                                                                                                                                                                                                                                                                                                                                          Submit a Featuring Nomination

                                                                                                                                                                                                                                                                                                                                                                                                                          New Broadcast Push Notification Metrics Now Available in the Push Notifications Console

                                                                                                                                                                                                                                                                                                                                                                                                                            The Push Notifications Console now includes metrics for broadcast push notifications sent in the Apple Push Notification service (APNs) production environment. The console’s interface provides an aggregated view of the broadcast push notifications that are successfully accepted by APNs, the number of devices that receive them, and a snapshot of the maximum number of devices subscribed to your channels.

                                                                                                                                                                                                                                                                                                                                                                                                                            Set up broadcast push notifications

                                                                                                                                                                                                                                                                                                                                                                                                                            Broadcast updates to your Live Activities

                                                                                                                                                                                                                                                                                                                                                                                                                            Coding in the kitchen: How Devin Davies whipped up the tasty recipe app Crouton

                                                                                                                                                                                                                                                                                                                                                                                                                              Let’s get this out of the way: Yes, Devin Davies is an excellent cook. “I’m not, like, a professional or anything,” he says, in the way that people say they’re not good at something when they are.

                                                                                                                                                                                                                                                                                                                                                                                                                              But in addition to knowing his way around the kitchen, Davies is also a seasoned developer whose app Crouton, a Swift-built cooking aid, won him the 2024 Apple Design Award for Interaction.

                                                                                                                                                                                                                                                                                                                                                                                                                              Crouton is part recipe manager, part exceptionally organized kitchen assistant. For starters, the app collects recipes from wherever people find them — blogs, family cookbooks, scribbled scraps from the ’90s, wherever — and uses tasty ML models to import and organize them. “If you find something online, just hit the Share button to pull it into Crouton,” says the New Zealand-based developer. “If you find a recipe in an old book, just snap a picture to save it.”

                                                                                                                                                                                                                                                                                                                                                                                                                              And when it’s time to start cooking, Crouton reduces everything to the basics by displaying only the current step, ingredients, and measurements (including conversions). There’s no swiping around between apps to figure out how many fl oz are in a cup; no setting a timer in a different app. It’s all handled right in Crouton. “The key for me is: How quickly can I get you back to preparing the meal, rather than reading?” Davies says.

                                                                                                                                                                                                                                                                                                                                                                                                                              ADA FACT SHEET

                                                                                                                                                                                                                                                                                                                                                                                                                              Crouton
                                                                                                                                                                                                                                                                                                                                                                                                                              • Winner: Interaction
                                                                                                                                                                                                                                                                                                                                                                                                                              • Available on: iPhone, iPad, Mac, Apple Vision Pro, Apple Watch
                                                                                                                                                                                                                                                                                                                                                                                                                              • Team size: 1

                                                                                                                                                                                                                                                                                                                                                                                                                              Learn more about Crouton

                                                                                                                                                                                                                                                                                                                                                                                                                              Download Crouton from the App Store

                                                                                                                                                                                                                                                                                                                                                                                                                              Crouton is the classic case of a developer whipping up something he needed. As the de facto chef in the house, Davies had previously done his meal planning in the Notes app, which worked until, as he laughs, “it got a little out of hand.”

                                                                                                                                                                                                                                                                                                                                                                                                                              At the time, Davies was in his salad days as an iOS developer, so he figured he could build something that would save him a little time. (It’s in his blood: Davies’s father is a developer too.) "Programming was never my strong suit,” he says, “but once I started building something that solved a problem, I started thinking of programming as a means to an end, and that helped.”

                                                                                                                                                                                                                                                                                                                                                                                                                              Davies’s full-time job was his meal ticket, but he started teaching himself Swift on the side. Swift, he says, clicked a lot faster than the other languages he’d tried, especially as someone who was still developing a taste for programming. “It still took me a while to get my head into it,” he says, “but I found pretty early on that Swift worked the way I wanted a language to work. You can point Crouton at some text, import that text, and do something with it. The amount of steps you don’t have to think about is astounding.”

                                                                                                                                                                                                                                                                                                                                                                                                                              I found pretty early on that Swift worked the way I wanted a language to work.

                                                                                                                                                                                                                                                                                                                                                                                                                              Devin Davies, Crouton

                                                                                                                                                                                                                                                                                                                                                                                                                              Coding with Swift offered plenty of baked-in benefits. Davies leaned on platform conventions to make navigating Crouton familiar and easy. Lists and collection views took advantage of Camera APIs. VisionKit powered text recognition; a separate model organized imported ingredients by category.

                                                                                                                                                                                                                                                                                                                                                                                                                              “I could separate out a roughly chopped onion from a regular onion and then add the quantity using a Core ML model,” he says. “It’s amazing how someone like me can build a model to detect ingredients when I really have zero understanding of how it works.”

                                                                                                                                                                                                                                                                                                                                                                                                                              Davies designed Crouton with simplicity in mind at all times. “I spent a lot of time figuring out what to leave out rather than bring in,” he says.

                                                                                                                                                                                                                                                                                                                                                                                                                              The app came together quickly: The first version was done in about six months, but Crouton simmered for a while before finding its audience. “My mom and I were the main active users for maybe a year,” Davies laughs. “But it’s really important to build something that you use yourself — especially when you’re an indie — so there’s motivation to carry on.”

                                                                                                                                                                                                                                                                                                                                                                                                                              Davies served up Crouton updates for a few years, and eventually the app gained more traction, culminating with its Apple Design Award for Interaction at WWDC24. That’s an appropriate category, Davies says, because he believes his approach to interaction is his app’s special sauce. “My skillset is figuring out how the pieces of an app fit together, and how you move through them from point A to B to C,” he says. “I spent a lot of time figuring out what to leave out rather than bring in.”

                                                                                                                                                                                                                                                                                                                                                                                                                              Crouton recipes can be imported from blogs, cookbook, scraps of paper, or anywhere else they might be found.

                                                                                                                                                                                                                                                                                                                                                                                                                              Davies hopes to use the coming months to explore spicing up Crouton with Apple Intelligence, Live Activities on Apple Watch, and translation APIs. (Though Crouton is his primary app, he’s also built an Apple Vision Pro app called Plate Smash, which is presumably very useful for cooking stress relief.)

                                                                                                                                                                                                                                                                                                                                                                                                                              But it’s important to him that any new features or upgrades pair nicely with the current Crouton. “I’m a big believer in starting out with core intentions and holding true to them,” he says. “I don’t think that the interface, over time, has to be completely different.”

                                                                                                                                                                                                                                                                                                                                                                                                                              My skillset is figuring out how the pieces of an app fit together, and how you move through them from point A to B to C.

                                                                                                                                                                                                                                                                                                                                                                                                                              Devin Davies, Crouton

                                                                                                                                                                                                                                                                                                                                                                                                                              Because it’s a kitchen assistant, Crouton is a very personal app. It’s in someone’s kitchen at mealtime, it’s helping people prepare means for their loved ones, it’s enabling them to expand their culinary reach. It makes a direct impact on a person’s day. That’s a lot of influence to have as an app developer — even when a recipe doesn’t quite pan out.

                                                                                                                                                                                                                                                                                                                                                                                                                              “Sometimes I’ll hear from people who discover a bug, or even a kind of misunderstanding, but they’re always very kind about it,” laughs Davies. “They’ll tell me, ‘Oh, I was baking a cake for my daughter’s birthday, and I put in way too much cream cheese and I ruined it. But, great app!’”

                                                                                                                                                                                                                                                                                                                                                                                                                              Meet the 2024 Apple Design Award winners

                                                                                                                                                                                                                                                                                                                                                                                                                              Behind the Design is a series that explores design practices and philosophies from finalists and winners of the Apple Design Awards. In each story, we go behind the screens with the developers and designers of these award-winning apps and games to discover how they brought their remarkable creations to life.

                                                                                                                                                                                                                                                                                                                                                                                                                              Hello Developer: November 2024

                                                                                                                                                                                                                                                                                                                                                                                                                                In this edition: The Swift Pathway, new developer activities around the world, and an interview with the creator of recipe app Crouton.

                                                                                                                                                                                                                                                                                                                                                                                                                                Read the full article

                                                                                                                                                                                                                                                                                                                                                                                                                                Upcoming changes to the App Store Receipt Signing Intermediate Certificate

                                                                                                                                                                                                                                                                                                                                                                                                                                  As part of ongoing efforts to improve security and privacy on Apple platforms, the App Store receipt signing intermediate certificate is being updated to use the SHA-256 cryptographic algorithm. This certificate is used to sign App Store receipts, which are the proof of purchase for apps and In-App Purchases.

                                                                                                                                                                                                                                                                                                                                                                                                                                  This update is being completed in multiple phases and some existing apps on the App Store may be impacted by the next update, depending on how they verify receipts.

                                                                                                                                                                                                                                                                                                                                                                                                                                  Starting January 24, 2025, if your app performs on-device receipt validation and doesn't support a SHA-256 algorithm, your app will fail to validate the receipt. If your app prevents customers from accessing the app or premium content when receipt validation fails, your customers may lose access to their content.

                                                                                                                                                                                                                                                                                                                                                                                                                                  If your app performs on-device receipt validation, update your app to support certificates that use the SHA-256 algorithm; alternatively, use the AppTransaction and Transaction APIs to verify App Store transactions.

                                                                                                                                                                                                                                                                                                                                                                                                                                  For more details, view TN3138: Handling App Store receipt signing certificate change.

                                                                                                                                                                                                                                                                                                                                                                                                                                  TestFlight enhancements to help you reach testers

                                                                                                                                                                                                                                                                                                                                                                                                                                    Beta testing your apps, games, and App Clips is even better with new enhancements to TestFlight. Updates include:

                                                                                                                                                                                                                                                                                                                                                                                                                                    • Redesigned invitations. TestFlight invitations now include your beta app description to better highlight new features and content your app or game offers to prospective testers. Apps and games with an approved version that’s ready for distribution can also include their screenshots and app category in their invite. We’ve also added a way for people to leave feedback if they didn’t join your beta, so you can understand why they didn’t participate.
                                                                                                                                                                                                                                                                                                                                                                                                                                    • Tester enrollment criteria. You can choose to set criteria, such as device type and OS versions, to more easily enroll qualified testers via a public link to provide more relevant feedback on your invite.
                                                                                                                                                                                                                                                                                                                                                                                                                                    • Public link metrics. Find out how successful your public link is at enrolling testers for your app with new metrics. Understand how many testers viewed your invite in the TestFlight app and chose to accept it. If you’ve set criteria for the public link, you can also view how many testers didn’t meet the criteria.

                                                                                                                                                                                                                                                                                                                                                                                                                                    To get started with TestFlight, upload your build, add test information, and invite testers.

                                                                                                                                                                                                                                                                                                                                                                                                                                    Learn more about TestFlight

                                                                                                                                                                                                                                                                                                                                                                                                                                    Get ready with the latest beta releases

                                                                                                                                                                                                                                                                                                                                                                                                                                      The beta versions of iOS 18.2, iPadOS 18.2, and macOS 15.2 are now available. Get your apps ready by confirming they work as expected on these releases. And make sure to build and test with Xcode 16.2 beta to take advantage of the advancements in the latest SDKs.

                                                                                                                                                                                                                                                                                                                                                                                                                                      As previewed earlier this year, changes to the browser choice screen, default apps, and app deletion for EU users, as well as support in Safari for exporting user data and for web browsers to import that data, are now available in the beta versions of iOS 18.2 and iPadOS 18.2.

                                                                                                                                                                                                                                                                                                                                                                                                                                      These releases also include improvements to the Apps area in Settings first introduced in iOS 18 and iPadOS 18. All users worldwide will be able to manage their default apps via a Default Apps section at the top of the Apps area. New calling and messaging defaults are also now available for all users worldwide.

                                                                                                                                                                                                                                                                                                                                                                                                                                      Following feedback from the European Commission and from developers, in these releases developers can develop and test EU-specific features, such as alternative browser engines, contactless apps, marketplace installations from web browsers, and marketplace apps, from anywhere in the world. Developers of apps that use alternative browser engines can now use WebKit in those same apps.

                                                                                                                                                                                                                                                                                                                                                                                                                                      View details about the browser choice screen, how to make an app available for users to choose as a default, how to create a calling or messaging app that can be a default, and how to import user data from Safari.

                                                                                                                                                                                                                                                                                                                                                                                                                                      Updated agreements now available

                                                                                                                                                                                                                                                                                                                                                                                                                                        The Apple Developer Program License Agreement and its Schedules 1, 2, and 3 have been updated to support updated policies and upcoming features, and to provide clarification. Please review the changes below and accept the updated terms in your account.

                                                                                                                                                                                                                                                                                                                                                                                                                                        Apple Developer Program License Agreement

                                                                                                                                                                                                                                                                                                                                                                                                                                        • Definitions, Section 3.3.3(J): Specified requirements for use of App Intents.
                                                                                                                                                                                                                                                                                                                                                                                                                                        • Definitions, Section 3.3.5(C): Clarified requirements for use of Sign in With Apple.
                                                                                                                                                                                                                                                                                                                                                                                                                                        • Definitions, Section 3.3.8(G): Specified requirements for use of the Critical Messaging API.
                                                                                                                                                                                                                                                                                                                                                                                                                                        • Definitions, Sections 3.3.9(C): Clarified requirements for use of the Apple Pay APIs; updated definition of “Apple” for use of the Apple Pay APIs.
                                                                                                                                                                                                                                                                                                                                                                                                                                        • Attachment 2: Clarified requirements for use of the In-App Purchase API.

                                                                                                                                                                                                                                                                                                                                                                                                                                        Schedules 1, 2, and 3

                                                                                                                                                                                                                                                                                                                                                                                                                                        Apple Services Pte. Ltd. is now the Apple legal entity responsible for the marketing and End-User download of the Licensed and Custom Applications by End-Users located in the following regions:

                                                                                                                                                                                                                                                                                                                                                                                                                                        • Bhutan
                                                                                                                                                                                                                                                                                                                                                                                                                                        • Brunei
                                                                                                                                                                                                                                                                                                                                                                                                                                        • Cambodia
                                                                                                                                                                                                                                                                                                                                                                                                                                        • Fiji
                                                                                                                                                                                                                                                                                                                                                                                                                                        • Korea
                                                                                                                                                                                                                                                                                                                                                                                                                                        • Laos
                                                                                                                                                                                                                                                                                                                                                                                                                                        • Macau
                                                                                                                                                                                                                                                                                                                                                                                                                                        • Maldives
                                                                                                                                                                                                                                                                                                                                                                                                                                        • Micronesia, Fed States of
                                                                                                                                                                                                                                                                                                                                                                                                                                        • Mongolia
                                                                                                                                                                                                                                                                                                                                                                                                                                        • Myanmar
                                                                                                                                                                                                                                                                                                                                                                                                                                        • Nauru
                                                                                                                                                                                                                                                                                                                                                                                                                                        • Nepal
                                                                                                                                                                                                                                                                                                                                                                                                                                        • Papua New Guinea
                                                                                                                                                                                                                                                                                                                                                                                                                                        • Palau
                                                                                                                                                                                                                                                                                                                                                                                                                                        • Solomon Islands
                                                                                                                                                                                                                                                                                                                                                                                                                                        • Sri Lanka
                                                                                                                                                                                                                                                                                                                                                                                                                                        • Tonga
                                                                                                                                                                                                                                                                                                                                                                                                                                        • Vanuatu

                                                                                                                                                                                                                                                                                                                                                                                                                                        Paid Applications Agreement (Schedules 2 and 3)

                                                                                                                                                                                                                                                                                                                                                                                                                                        Exhibit B: Indicated that Apple shall not collect and remit taxes for local developers in Nepal and Kazakhstan, and such developers shall be solely responsible for the collection and remittance of such taxes as may be required by local law.

                                                                                                                                                                                                                                                                                                                                                                                                                                        Exhibit C:

                                                                                                                                                                                                                                                                                                                                                                                                                                        1. Section 6: Clarified that Apple will apply Korean VAT on the commissions payable by Korean developers to Apple to be deducted from remittance with respect to sales to Korean customers pursuant to local tax laws.
                                                                                                                                                                                                                                                                                                                                                                                                                                        2. Section 10: For Singaporean developers who have registered for Singapore GST and have provided their Singapore GST registration number to Apple, clarified that Apple will apply Singaporean GST on the commissions payable by Singaporean developers to Apple to be deducted from remittance with respect to sales to Singaporean customers pursuant to local tax laws.

                                                                                                                                                                                                                                                                                                                                                                                                                                        View the full terms and conditions

                                                                                                                                                                                                                                                                                                                                                                                                                                        Translations of the Apple Developer Program License Agreement will be available on the Apple Developer website within one month.

                                                                                                                                                                                                                                                                                                                                                                                                                                        New requirement for app updates in the European Union

                                                                                                                                                                                                                                                                                                                                                                                                                                          Starting today, in order to submit updates for apps on the App Store in the European Union (EU) Account Holders or Admins in the Apple Developer Program need to enter trader status in App Store Connect. If you’re a trader, you’ll need to provide your trader information before you can submit your app for review.

                                                                                                                                                                                                                                                                                                                                                                                                                                          Starting February 17, 2025, apps without trader status will be removed from the App Store in the EU until trader status is provided and verified in order to comply with the Digital Services Act.

                                                                                                                                                                                                                                                                                                                                                                                                                                          Learn what a trader is and how to enter your status

                                                                                                                                                                                                                                                                                                                                                                                                                                          Apple Push Notification service server certificate update

                                                                                                                                                                                                                                                                                                                                                                                                                                            The Certification Authority (CA) for Apple Push Notification service (APNs) is changing. APNs will update the server certificates in sandbox on January 20, 2025, and in production on February 24, 2025. All developers using APNs will need to update their application’s Trust Store to include the new server certificate: SHA-2 Root : USERTrust RSA Certification Authority certificate.

                                                                                                                                                                                                                                                                                                                                                                                                                                            To ensure a smooth transition and avoid push notification delivery failures, please make sure that both old and new server certificates are included in the Trust Store before the cut-off date for each of your application servers that connect to sandbox and production.

                                                                                                                                                                                                                                                                                                                                                                                                                                            At this time, you don’t need to update the APNs SSL provider certificates issued to you by Apple.

                                                                                                                                                                                                                                                                                                                                                                                                                                            Hello Developer: October 2024

                                                                                                                                                                                                                                                                                                                                                                                                                                              Get your app up to speed, meet the team behind Lies of P, explore new student resources, and more.

                                                                                                                                                                                                                                                                                                                                                                                                                                              Read the full article

                                                                                                                                                                                                                                                                                                                                                                                                                                              Masters of puppets: How ROUND8 Studio carved out a niche for Lies of P

                                                                                                                                                                                                                                                                                                                                                                                                                                                Lies of P is closer to its surprising source material than you might think.

                                                                                                                                                                                                                                                                                                                                                                                                                                                Based on Carlo Collodi’s 1883 novel The Adventures of Pinocchio, the Apple Design Award-winning game is a macabre reimagining of the story of a puppet who longs to be a real boy. Collodi’s story is still best known as a children’s fable. But it’s also preprogrammed with more than its share of darkness — which made it an appealing foundation for Lies of P director Jiwon Choi.

                                                                                                                                                                                                                                                                                                                                                                                                                                                “When we were looking for stories to base the game on, we had a checklist of needs,” says Choi. “We wanted something dark. We wanted a story that was familiar but not entirely childish. And the deeper we dove into Pinocchio, the more we found that it checked off everything we were looking for.”

                                                                                                                                                                                                                                                                                                                                                                                                                                                ADA FACT SHEET

                                                                                                                                                                                                                                                                                                                                                                                                                                                Lies of P
                                                                                                                                                                                                                                                                                                                                                                                                                                                • Winner: Visuals and Graphics
                                                                                                                                                                                                                                                                                                                                                                                                                                                • Team: ROUND8 Studio (developer), NEOWIZ (publisher)
                                                                                                                                                                                                                                                                                                                                                                                                                                                • Available on: Mac
                                                                                                                                                                                                                                                                                                                                                                                                                                                • Team size: 100
                                                                                                                                                                                                                                                                                                                                                                                                                                                • Previous accolades: App Store 2023 Mac Game of the Year, App Store Editors’ Choice

                                                                                                                                                                                                                                                                                                                                                                                                                                                Developed by the South Korea-based ROUND8 Studio and published by its parent company, NEOWIZ, Lies of P is a lavishly rendered dark fantasy adventure and a technical showpiece for Mac with Apple silicon. Yes, players control a humanoid puppet created by Geppetto. But instead of a little wooden boy with a penchant for little white lies, the game’s protagonist is a mechanical warrior with an array of massive swords and a mission to battle through the burned-out city of Krat to find his maker — who isn’t exactly the genial old woodcarver from the fable.

                                                                                                                                                                                                                                                                                                                                                                                                                                                “The story is well-known, and so are the characters,” says Choi. “We knew that to create a lasting memory for gamers, we had to add our own twists.”

                                                                                                                                                                                                                                                                                                                                                                                                                                                In the burned-out world of Lies of P, something this warm and beautiful can’t be good news.

                                                                                                                                                                                                                                                                                                                                                                                                                                                Those twists abound. The puppet is accompanied by a digital lamp assistant named Gemini — pronounced “jim-i-nee,” of course. A major character is a play on the original’s kindly Blue Fairy. A game boss named Mad Donkey is a lot more irritable than the donkeys featured in Collodi’s story. And though nobody’s nose grows in Lies of P, characters have opportunities to lie in a way that directly affects the storyline — and potentially one of the game’s multiple endings.

                                                                                                                                                                                                                                                                                                                                                                                                                                                We knew that to create a lasting memory for gamers, we had to add our own twists.

                                                                                                                                                                                                                                                                                                                                                                                                                                                Jiwon Choi, Lies of P director

                                                                                                                                                                                                                                                                                                                                                                                                                                                “If you play without knowing the original story, you might not catch all those twists,” says Choi. “But it goes the other way, too. We’ve heard from players who became curious about the original story, so they went back and found out about our twists that way.”

                                                                                                                                                                                                                                                                                                                                                                                                                                                There’s nothing curious about the game’s success: In addition to winning a 2024 Apple Design Award for Visuals and Graphics, Lies of P was named the App Store’s 2023 Mac Game of the Year and has collected a bounty of accolades from the gaming community. Many of those call out the game’s visual beauty, a world of rich textures, detailed lighting, and visual customization options like MetalFX upscaling and volumetric fog effects that let you style the ruined city to your liking.

                                                                                                                                                                                                                                                                                                                                                                                                                                                Many of Collodi’s original characters have been updated for Lies of P, including the Black Rabbit Brotherhood, who appear to be hopping mad.

                                                                                                                                                                                                                                                                                                                                                                                                                                                For that city, the ROUND8 team added another twist by moving the story from its original Italian locale to the Belle Èpoque era of pre-WWI France. “Everyone expected Italy, and everyone expected steampunk,” says Choi, “but we wanted something that wasn’t quite as common in the gaming industry. We considered a few other locations, like the wild west, but the Belle Èpoque was the right mix of beauty and prosperity. We just made it darker and gloomier.”

                                                                                                                                                                                                                                                                                                                                                                                                                                                We considered a few other locations, like the wild west, but the Belle Èpoque was the right mix of beauty and prosperity. We just made it darker and gloomier.

                                                                                                                                                                                                                                                                                                                                                                                                                                                Jiwon Choi, Lies of P director

                                                                                                                                                                                                                                                                                                                                                                                                                                                To create the game’s fierce (and oily) combat, Choi and the team took existing Soulslike elements and added their own touches, like customizable weapons that can be assembled from items lying around Krat. “We found that players will often find a weapon they like and use it until the ending,” says Choi. “We found that inefficient. But we also know that everyone has a different taste for weapons.”

                                                                                                                                                                                                                                                                                                                                                                                                                                                The system, he says, gives players the freedom to choose their own combinations instead of pursuing a “best” pre-ordained weapon. And the strategy worked: Choi says players are often found online discussing the best combinations rather than the best weapons. “That was our intention when creating the system,” he says.

                                                                                                                                                                                                                                                                                                                                                                                                                                                The game is set in the Belle Èpoque, an era known for its beauty and prosperity. “We just made it darker and gloomier,” says Choi.

                                                                                                                                                                                                                                                                                                                                                                                                                                                Also intentional: The game’s approach to lying, another twist on the source material. “Lying in the game isn’t just about deceiving a counterpart,” says Choi. “Humans are the only species who can lie to one another, so lying is about exploring the core of this character.”

                                                                                                                                                                                                                                                                                                                                                                                                                                                It’s also about the murky ethics of lying: Lies of P suggests that, at times, nothing is as human — or humane — as a well-intentioned falsehood.

                                                                                                                                                                                                                                                                                                                                                                                                                                                “The puppet of Geppetto is not human,” says Choi. “But at the same time, the puppet acts like a human and occasionally exhibits human behavior, like getting emotional listening to music. The idea was: Lying is something a human might do. That’s why it’s part of the game.”

                                                                                                                                                                                                                                                                                                                                                                                                                                                Every environment in Lies of P — including the Krat Festival, which has seen better days — is rich with desolate detail.

                                                                                                                                                                                                                                                                                                                                                                                                                                                The Lies of P story might not be done just yet. Choi and team are working on downloadable content and a potential sequel — possibly starring another iconic character who’s briefly teased in the game’s ending. But in the meantime, the team is taking a moment to enjoy the fruits of their success. “At the beginning of development, I honestly doubted that we could even pull this off,” says Choi. “For me, the most surprising thing is that we achieved this. And that makes us think, ‘Well, maybe we could do better next time.’”

                                                                                                                                                                                                                                                                                                                                                                                                                                                Meet the 2024 Apple Design Award winners

                                                                                                                                                                                                                                                                                                                                                                                                                                                Behind the Design is a series that explores design practices and philosophies from finalists and winners of the Apple Design Awards. In each story, we go behind the screens with the developers and designers of these award-winning apps and games to discover how they brought their remarkable creations to life.

                                                                                                                                                                                                                                                                                                                                                                                                                                                Announcing the Swift Student Challenge 2025

                                                                                                                                                                                                                                                                                                                                                                                                                                                  We’re thrilled to announce the Swift Student Challenge 2025. The Challenge provides the next generation of student developers the opportunity to showcase their creativity and coding skills by building app playgrounds with Swift.

                                                                                                                                                                                                                                                                                                                                                                                                                                                  Applications for the next Challenge will open in February 2025 for three weeks.

                                                                                                                                                                                                                                                                                                                                                                                                                                                  We’ll select 350 Swift Student Challenge winners whose submissions demonstrate excellence in innovation, creativity, social impact, or inclusivity. From this esteemed group, we’ll name 50 Distinguished Winners whose work is truly exceptional and invite them to join us at Apple in Cupertino for three incredible days where they’ll gain invaluable insights from Apple experts and engineers, connect with their peers, and enjoy a host of unforgettable experiences.

                                                                                                                                                                                                                                                                                                                                                                                                                                                  All Challenge winners will receive one year of membership in the Apple Developer Program, a special gift from Apple, and more.

                                                                                                                                                                                                                                                                                                                                                                                                                                                  To help you get ready, we’re launching new coding resources, including Swift Coding Clubs designed for students to develop skills for a future career, build community, and get ready for the Challenge.

                                                                                                                                                                                                                                                                                                                                                                                                                                                  Learn more

                                                                                                                                                                                                                                                                                                                                                                                                                                                  Upcoming regional age ratings in Australia and France

                                                                                                                                                                                                                                                                                                                                                                                                                                                    Apple is committed to making the App Store a safe place for everyone — especially kids. Within the next few months, the following regional age ratings for Australia and France will be implemented in accordance with local laws. No action is needed on your part. Where required by local regulations, regional ratings will appear alongside Apple global age ratings.

                                                                                                                                                                                                                                                                                                                                                                                                                                                    Australia

                                                                                                                                                                                                                                                                                                                                                                                                                                                    Apps with any instances of simulated gambling will display an R18+ regional age rating in addition to the Apple global age rating on the App Store in Australia.

                                                                                                                                                                                                                                                                                                                                                                                                                                                    France

                                                                                                                                                                                                                                                                                                                                                                                                                                                    Apps with a 17+ Apple global age rating will also display an 18+ regional age rating on the App Store in France.

                                                                                                                                                                                                                                                                                                                                                                                                                                                    Learn more about the age ratings

                                                                                                                                                                                                                                                                                                                                                                                                                                                    Update on iPadOS 18 apps distributed in the European Union

                                                                                                                                                                                                                                                                                                                                                                                                                                                      The App Review Guidelines have been revised to add iPadOS to Notarization.

                                                                                                                                                                                                                                                                                                                                                                                                                                                      Starting September 16:

                                                                                                                                                                                                                                                                                                                                                                                                                                                      • Users in the EU can download iPadOS apps on the App Store and through alternative distribution. As mentioned in May, if you have entered into the Alternative Terms Addendum for Apps in the EU, iPadOS first annual installs will begin to accrue and the lower App Store commission rate will apply.
                                                                                                                                                                                                                                                                                                                                                                                                                                                      • Alternative browser engines can be used in iPadOS apps.
                                                                                                                                                                                                                                                                                                                                                                                                                                                      • Historical App Install Reports in App Store Connect that can be used with our fee calculator will include iPadOS.

                                                                                                                                                                                                                                                                                                                                                                                                                                                      If you’ve entered into a previous version of the following agreements, be sure to sign the latest version, which supports iPadOS:

                                                                                                                                                                                                                                                                                                                                                                                                                                                      Learn more about the update on apps distributed in the EU

                                                                                                                                                                                                                                                                                                                                                                                                                                                      Translations of the guidelines will be available on the Apple Developer website within one month.

                                                                                                                                                                                                                                                                                                                                                                                                                                                      Win-back offers for auto-renewable subscriptions now available

                                                                                                                                                                                                                                                                                                                                                                                                                                                        You can now configure win-back offers — a new type of offer for auto-renewable subscriptions — in App Store Connect. Win-back offers allow you to reach previous subscribers and encourage them to resubscribe to your app or game. For example, you can create a pay up front offer for a reduced subscription price of $9.99 for six months, with a standard renewal price of $39.99 per year. Based on your offer configuration, Apple displays these offers to eligible customers in various places, including:

                                                                                                                                                                                                                                                                                                                                                                                                                                                        • Across the App Store, including on your product page, as well as in personalized recommendations and editorial selections on the Today, Games, and Apps tabs.
                                                                                                                                                                                                                                                                                                                                                                                                                                                        • In your app or game.
                                                                                                                                                                                                                                                                                                                                                                                                                                                        • Via a direct link you share using your own marketing channels.
                                                                                                                                                                                                                                                                                                                                                                                                                                                        • In Subscription settings.

                                                                                                                                                                                                                                                                                                                                                                                                                                                        When creating win-back offers in App Store Connect, you’ll determine customer eligibility, select regional availability, and choose the discount type. Eligible customers will be able to discover win-back offers this fall.

                                                                                                                                                                                                                                                                                                                                                                                                                                                        Set up win-back offers

                                                                                                                                                                                                                                                                                                                                                                                                                                                        Learn about win-back offers

                                                                                                                                                                                                                                                                                                                                                                                                                                                        App Store submissions now open for the latest OS releases

                                                                                                                                                                                                                                                                                                                                                                                                                                                          iOS 18, iPadOS 18, macOS Sequoia, tvOS 18, visionOS 2, and watchOS 11 will soon be available to customers worldwide. Build your apps and games using the Xcode 16 Release Candidate and latest SDKs, test them using TestFlight, and submit them for review to the App Store. You can now start deploying seamlessly to TestFlight and the App Store from Xcode Cloud. With exciting new features like watchOS Live Activities, app icon customization, and powerful updates to Swift, Siri, Controls, and Core ML, you can deliver even more unique experiences on Apple platforms.

                                                                                                                                                                                                                                                                                                                                                                                                                                                          And beginning next month, you’ll be able to bring the incredible new features of Apple Intelligence into your apps to help inspire the way users communicate, work, and express themselves.

                                                                                                                                                                                                                                                                                                                                                                                                                                                          Starting April 2025, apps uploaded to App Store Connect must be built with SDKs for iOS 18, iPadOS 18, tvOS 18, visionOS 2, or watchOS 11.

                                                                                                                                                                                                                                                                                                                                                                                                                                                          Learn about submitting apps

                                                                                                                                                                                                                                                                                                                                                                                                                                                          Hello Developer: September 2024

                                                                                                                                                                                                                                                                                                                                                                                                                                                            Get your apps ready by digging into these video sessions and resources.

                                                                                                                                                                                                                                                                                                                                                                                                                                                            Explore machine learning on Apple platforms Watch now Bring expression to your app with Genmoji Watch now Browse new resources

                                                                                                                                                                                                                                                                                                                                                                                                                                                            Learn how to make actions available to Siri and Apple Intelligence.

                                                                                                                                                                                                                                                                                                                                                                                                                                                            Need a boost?

                                                                                                                                                                                                                                                                                                                                                                                                                                                            Check out our curated guide to machine learning and AI.

                                                                                                                                                                                                                                                                                                                                                                                                                                                            FEATURED

                                                                                                                                                                                                                                                                                                                                                                                                                                                            Get ready for OS updates

                                                                                                                                                                                                                                                                                                                                                                                                                                                            Dive into the latest updates with these developer sessions.

                                                                                                                                                                                                                                                                                                                                                                                                                                                            Level up your games Port advanced games to Apple platforms Watch now Design advanced games for Apple platforms Watch now Bring your vision to life Design great visionOS apps Watch now Design interactive experiences for visionOS Watch now Upgrade your iOS and iPadOS apps Extend your app’s controls across the system Watch now Elevate your tab and sidebar experience in iPadOS Watch now

                                                                                                                                                                                                                                                                                                                                                                                                                                                            Browse Apple Developer on YouTube

                                                                                                                                                                                                                                                                                                                                                                                                                                                            Get expert guidance

                                                                                                                                                                                                                                                                                                                                                                                                                                                            Check out curated guides to the latest features and technologies.

                                                                                                                                                                                                                                                                                                                                                                                                                                                            BEHIND THE DESIGN

                                                                                                                                                                                                                                                                                                                                                                                                                                                            Rytmos: A puzzle game with a global beat

                                                                                                                                                                                                                                                                                                                                                                                                                                                            Find out how Floppy Club built an Apple Design Award winner that sounds as good as it looks.

                                                                                                                                                                                                                                                                                                                                                                                                                                                            Behind the Design: The rhythms of Rytmos View now

                                                                                                                                                                                                                                                                                                                                                                                                                                                            MEET WITH APPLE

                                                                                                                                                                                                                                                                                                                                                                                                                                                            Reserve your spot for upcoming developer activities Subscribe to Hello Developer

                                                                                                                                                                                                                                                                                                                                                                                                                                                            Want to get Hello Developer in your inbox? Make sure you’ve opted in to receive emails about developer news and events by updating your email preferences in your developer account.

                                                                                                                                                                                                                                                                                                                                                                                                                                                            Share your thoughts

                                                                                                                                                                                                                                                                                                                                                                                                                                                            We’d love to hear from you. If you have suggestions for our activities or stories, please let us know.

                                                                                                                                                                                                                                                                                                                                                                                                                                                            Behind the Design: The rhythms of Rytmos

                                                                                                                                                                                                                                                                                                                                                                                                                                                              Rytmos is a game that sounds as good as it looks.

                                                                                                                                                                                                                                                                                                                                                                                                                                                              With its global rhythms, sci-fi visuals, and clever puzzles, the 2024 Apple Design Award winner for Interaction is both a challenge and an artistic achievement. To solve each level, players must create linear pathways on increasingly complex boards, dodging obstacles and triggering buttons along the way. It’s all set to a world-music backdrop; different levels feature genres as diverse as Ethiopian jazz, Hawaiian slack key guitar, and Gamelan from Indonesia, just to name a few.

                                                                                                                                                                                                                                                                                                                                                                                                                                                              And here’s the hook: Every time you clear a level, you add an instrument to an ever-growing song.

                                                                                                                                                                                                                                                                                                                                                                                                                                                              “The idea is that instead of reacting to the music, you’re creating it,” says Asger Strandby, cofounder of Floppy Club, the Denmark-based studio behind Rytmos. “We do a lot to make sure it doesn’t sound too wild. But the music in Rytmos is entirely generated by the way you solve the puzzles.”

                                                                                                                                                                                                                                                                                                                                                                                                                                                              ADA FACT SHEET

                                                                                                                                                                                                                                                                                                                                                                                                                                                              Rytmos
                                                                                                                                                                                                                                                                                                                                                                                                                                                              • Winner: Interaction
                                                                                                                                                                                                                                                                                                                                                                                                                                                              • Team: Floppy Club
                                                                                                                                                                                                                                                                                                                                                                                                                                                              • Available on: iPhone, iPad
                                                                                                                                                                                                                                                                                                                                                                                                                                                              • Team size: 5

                                                                                                                                                                                                                                                                                                                                                                                                                                                              Learn more about Rytmos

                                                                                                                                                                                                                                                                                                                                                                                                                                                              Download Rytmos from the App Store

                                                                                                                                                                                                                                                                                                                                                                                                                                                              The artful game is the result of a partnership that dates back decades. In addition to being developers, Strandby and Floppy Club cofounder Niels Böttcher are both musicians who hail from the town of Aarhus in Denmark. “It’s a small enough place that if you work in music, you probably know everyone in the community,” laughs Böttcher.

                                                                                                                                                                                                                                                                                                                                                                                                                                                              The music in Rytmos comes mostly from traveling and being curious.

                                                                                                                                                                                                                                                                                                                                                                                                                                                              Niels Böttcher, Floppy Club cofounder

                                                                                                                                                                                                                                                                                                                                                                                                                                                              The pair connected back in the early 2000s, bonding over music more than games. “For me, games were this magical thing that you could never really make yourself,” says Strandby. “I was a geeky kid, so I made music and eventually web pages on computers, but I never really thought I could make games until I was in my twenties.” Instead, Strandby formed bands like Analogik, which married a wild variety of crate-digging samples — swing music, Eastern European folk, Eurovision-worthy pop — with hip-hop beats. Strandby was the frontman, while Böttcher handled the behind-the-scenes work. “I was the manager in everything but name,” he says.

                                                                                                                                                                                                                                                                                                                                                                                                                                                              The band was a success: Analogik went on to release five studio albums and perform at Glastonbury, Roskilde, and other big European festivals. But when their music adventure ended, the pair moved back into separate tech jobs for several years — until the time came to join forces again. “We found ourselves brainstorming one day, thinking about, ‘Could we combine music and games in some way?’” says Böttcher. “There are fun similarities between the two in terms of structures and patterns. We thought, ‘Well, let’s give it a shot.’”

                                                                                                                                                                                                                                                                                                                                                                                                                                                              Puzzles in Rytmos — like the one set on the planet “Hateta” — come with a little history lesson about the music being played.

                                                                                                                                                                                                                                                                                                                                                                                                                                                              The duo launched work on a rhythm game that was powered by their histories and travels. “I’ve collected CDs and tapes from all over the world, so the genres in Rytmos are very carefully chosen,” says Böttcher. “We really love Ethiopian jazz music, so we included that. Gamelan music (traditional Indonesian ensemble music that’s heavy on percussion) is pretty wild, but incredible. And sometimes, you just hear an instrument and say, ‘Oh, that tabla has a really nice sound.’ So the music in Rytmos comes mostly from traveling and being curious.”

                                                                                                                                                                                                                                                                                                                                                                                                                                                              The game took shape early, but the mazes in its initial versions were much more intricate. To help bring them down to a more approachable level, the Floppy Club team brought on art director Niels Fyrst. “He was all about making things cleaner and clearer,” says Böttcher. “Once we saw what he was proposing — and how it made the game stronger — we realized, ‘OK, maybe we’re onto something.’”

                                                                                                                                                                                                                                                                                                                                                                                                                                                              Success in Rytmos isn't just that you're beating a level. It's that you're creating something.

                                                                                                                                                                                                                                                                                                                                                                                                                                                              Asger Strandby, Floppy Club cofounder

                                                                                                                                                                                                                                                                                                                                                                                                                                                              Still, even with a more manageable set of puzzles, a great deal of design complexity remained. Building Rytmos levels was like stacking a puzzle on a puzzle; the team not only had to build out the levels, but also create the music to match. To do so, Strandby and his brother, Bo, would sketch out a level and then send it over to Böttcher, who would sync it to music — a process that proved even more difficult than it seems.

                                                                                                                                                                                                                                                                                                                                                                                                                                                              “The sound is very dependent on the location of the obstacles in the puzzles,” says Strandby. “That’s what shapes the music that comes out of the game. So we’d test and test again to make sure the sound didn’t break the idea of the puzzle.”

                                                                                                                                                                                                                                                                                                                                                                                                                                                              Puzzles in Rytmos are all about getting from Point A to Point B — but things are never as simple as they seem.

                                                                                                                                                                                                                                                                                                                                                                                                                                                              The process, he says, was “quite difficult” to get right. “Usually with something like this, you create a loop, and then maybe add another loop, and then add layers on top of it,” says Böttcher. “In Rytmos, hitting an emitter triggers a tone, percussion sound, or chord. One tone hits another tone, and then another, and then another. In essence, you’re creating a pattern while playing the game.”

                                                                                                                                                                                                                                                                                                                                                                                                                                                              We’ve actually gone back to make some of the songs more imprecise, because we want them to sound human.

                                                                                                                                                                                                                                                                                                                                                                                                                                                              Niels Böttcher, Floppy Club cofounder

                                                                                                                                                                                                                                                                                                                                                                                                                                                              The unorthodox approach leaves room for creativity. “Two different people’s solutions can sound different,” says Strandby. And when players win a level, they unlock a “jam mode” where they can play and practice freely. "It’s just something to do with no rules after all the puzzling,” laughs Strandby.

                                                                                                                                                                                                                                                                                                                                                                                                                                                              Yet despite all the technical magic happening behind the scenes, the actual musical results had to have a human feel. “We’re dealing with genres that are analog and organic, so they couldn’t sound electronic at all,” says Böttcher. “We’ve actually gone back to make some of the songs more imprecise, because we want them to sound human.”

                                                                                                                                                                                                                                                                                                                                                                                                                                                              Best of all, the game is shot through with creativity and cleverness — even offscreen. Each letter in the Rytmos logo represents the solution to a puzzle. The company’s logo is a 3.5-inch floppy disk, a little nod to their first software love. (“That’s all I wished for every birthday,” laughs Böttcher.) And both Böttcher and Strandby hope that the game serves as an introduction to both sounds and people they might not be familiar with. "Learning about music is a great way to learn about a culture,” says Strandby.

                                                                                                                                                                                                                                                                                                                                                                                                                                                              But mostly, Rytmos is an inspirational experience that meets its lofty goal. “Success in Rytmos isn’t just that you’re beating a level,” says Strandby. “It’s that you’re creating something.”

                                                                                                                                                                                                                                                                                                                                                                                                                                                              Meet the 2024 Apple Design Award winners

                                                                                                                                                                                                                                                                                                                                                                                                                                                              Behind the Design is a series that explores design practices and philosophies from finalists and winners of the Apple Design Awards. In each story, we go behind the screens with the developers and designers of these award-winning apps and games to discover how they brought their remarkable creations to life.

                                                                                                                                                                                                                                                                                                                                                                                                                                                              Price and tax updates for apps, In-App Purchases, and subscriptions

                                                                                                                                                                                                                                                                                                                                                                                                                                                                The App Store is designed to make it easy to sell your digital goods and services globally, with support for 44 currencies across 175 storefronts.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                From time to time, we may need to adjust prices or your proceeds due to changes in tax regulations or foreign exchange rates. These adjustments are made using publicly available exchange rate information from financial data providers to help make sure prices for apps and In-App Purchases stay consistent across all storefronts.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                Price updates

                                                                                                                                                                                                                                                                                                                                                                                                                                                                On September 16:

                                                                                                                                                                                                                                                                                                                                                                                                                                                                • Pricing for apps and In-App Purchases¹ will be updated for the Chile, Laos, and Senegal storefronts if you haven’t selected one of these as the base for your app or In‑App Purchase.¹ These updates also consider value‑added tax (VAT) introductions listed in the “Tax updates” section below.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                If you’ve selected the Chile, Laos, or Senegal storefront as the base for your app or In-App Purchase, prices won’t change. On other storefronts, prices will be updated to maintain equalization with your chosen base price.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                Prices won’t change in any region if your In‑App Purchase is an auto‑renewable subscription and won’t change on the storefronts where you manually manage prices instead of using the automated equalized prices.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                The Pricing and Availability section of Apps has been updated in App Store Connect to display these upcoming price changes. As always, you can change the prices of your apps, In‑App Purchases, and auto‑renewable subscriptions at any time.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                Learn more about managing your prices

                                                                                                                                                                                                                                                                                                                                                                                                                                                                View or edit upcoming price changes

                                                                                                                                                                                                                                                                                                                                                                                                                                                                Edit your app’s base country or region

                                                                                                                                                                                                                                                                                                                                                                                                                                                                Pricing and availability start times by region

                                                                                                                                                                                                                                                                                                                                                                                                                                                                Set a price for an In-App Purchase

                                                                                                                                                                                                                                                                                                                                                                                                                                                                Tax updates

                                                                                                                                                                                                                                                                                                                                                                                                                                                                As of August 29:

                                                                                                                                                                                                                                                                                                                                                                                                                                                                Your proceeds from the sale of eligible apps and In‑App Purchases have been modified in:

                                                                                                                                                                                                                                                                                                                                                                                                                                                                • Laos: VAT introduction of 10%
                                                                                                                                                                                                                                                                                                                                                                                                                                                                • Senegal: VAT introduction of 18%
                                                                                                                                                                                                                                                                                                                                                                                                                                                                • India: Equalization levy of 2% no longer applicable

                                                                                                                                                                                                                                                                                                                                                                                                                                                                Exhibit B of the Paid Applications Agreement has been updated to indicate that Apple collects and remits applicable taxes in Laos and Senegal.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                Beginning in September:

                                                                                                                                                                                                                                                                                                                                                                                                                                                                Your proceeds from the sale of eligible apps and In‑App Purchases will be modified in:

                                                                                                                                                                                                                                                                                                                                                                                                                                                                • Canada: Digital services tax introduction of 3%
                                                                                                                                                                                                                                                                                                                                                                                                                                                                • Finland: VAT increase from 24% to 25.5%

                                                                                                                                                                                                                                                                                                                                                                                                                                                                Learn more about your proceeds

                                                                                                                                                                                                                                                                                                                                                                                                                                                                View payments and proceeds

                                                                                                                                                                                                                                                                                                                                                                                                                                                                Download financial reports

                                                                                                                                                                                                                                                                                                                                                                                                                                                                1: Excludes auto-renewable subscriptions.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                It’s Glowtime.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                  Join us for a special Apple Event on September 9 at 10 a.m. PT.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                  Watch on apple.com, Apple TV, or YouTube Live.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                  Upcoming changes to the browser choice screen, default apps, and app deletion for EU users

                                                                                                                                                                                                                                                                                                                                                                                                                                                                    By the end of this year, we’ll make changes to the browser choice screen, default apps, and app deletion for iOS and iPadOS for users in the EU. These updates come from our ongoing and continuing dialogue with the European Commission about compliance with the Digital Market Act’s requirements in these areas.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                    Developers of browsers offered in the browser choice screen in the EU will have additional information about their browser shown to users who view the choice screen, and will get access to more data about the performance of the choice screen. The updated choice screen will be shown to all EU users who have Safari set as their default browser. For details about the changes coming to the browser choice screen, view About the browser choice screen in the EU.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                    For users in the EU, iOS 18 and iPadOS 18 will also include a new Default Apps section in Settings that lists defaults available to each user. In future software updates, users will get new default settings for dialing phone numbers, sending messages, translating text, navigation, managing passwords, keyboards, and call spam filters. To learn more, view Update on apps distributed in the European Union.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                    Additionally, the App Store, Messages, Photos, Camera, and Safari apps will now be deletable for users in the EU.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                    Upcoming requirements for app distribution in the European Union

                                                                                                                                                                                                                                                                                                                                                                                                                                                                      As a reminder, Account Holders or Admins in the Apple Developer Program need to enter trader status in App Store Connect for apps on the App Store in the European Union (EU) in order to comply with the Digital Services Act.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                      Please note these new dates and requirements:

                                                                                                                                                                                                                                                                                                                                                                                                                                                                      • October 16, 2024: Trader status will be required to submit app updates. If you’re a trader, you’ll need to provide your trader information before you can submit your app for review.
                                                                                                                                                                                                                                                                                                                                                                                                                                                                      • February 17, 2025: Apps without trader status will be removed from the App Store in the EU until trader status is provided and verified.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                      Learn what a trader is and how to enter your status

                                                                                                                                                                                                                                                                                                                                                                                                                                                                      Apple Entrepreneur Camp applications are now open

                                                                                                                                                                                                                                                                                                                                                                                                                                                                        Apple Entrepreneur Camp supports underrepresented founders and developers, and encourages the pipeline and longevity of these entrepreneurs in technology. Attendees benefit from one-on-one code-level guidance, receive unprecedented access to Apple engineers and experts, and become part of the extended global network of Apple Entrepreneur Camp alumni.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                        Applications are now open for female,* Black, Hispanic/Latinx, and Indigenous founders and developers. And this year we’re thrilled to bring back our in-person programming at Apple in Cupertino. For those who can’t attend in person, we’re still offering our full program online. We welcome established entrepreneurs with app-driven businesses to learn more about eligibility requirements and apply today.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                        Apply by September 3, 2024.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                        Learn more

                                                                                                                                                                                                                                                                                                                                                                                                                                                                        * Apple believes that gender expression is a fundamental right. We welcome all women to apply to this program.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                        Updates to the StoreKit External Purchase Link Entitlement

                                                                                                                                                                                                                                                                                                                                                                                                                                                                          In response to the announcement by the European Commission in June, we’re making the following changes to Apple’s Digital Markets Act compliance plan. We’re introducing updated terms that will apply this fall for developers with apps in the European Union storefronts of the App Store that use the StoreKit External Purchase Link Entitlement. Key changes include:

                                                                                                                                                                                                                                                                                                                                                                                                                                                                          • Developers can communicate and promote offers for purchases available at a destination of their choice. The destination can be an alternative app marketplace, another app, or a website, and it can be accessed outside the app or via a web view that appears in the app.
                                                                                                                                                                                                                                                                                                                                                                                                                                                                          • Developers may design and execute within their apps the communication and promotion of offers. This includes providing information about prices of subscriptions or any other offer available both within or outside the app, and providing explanations or instructions about how to subscribe to offers outside the application. These communications must provide accurate information regarding the digital goods or services available for purchase.
                                                                                                                                                                                                                                                                                                                                                                                                                                                                          • Developers may choose to use an actionable link that can be tapped, clicked, or scanned, to take users to their destination.
                                                                                                                                                                                                                                                                                                                                                                                                                                                                          • Developers can use any number of URLs, without declaring them in the app’s Info.plist.
                                                                                                                                                                                                                                                                                                                                                                                                                                                                          • Links with parameters, redirects, and intermediate links to landing pages are permitted.
                                                                                                                                                                                                                                                                                                                                                                                                                                                                          • Updated business terms for apps with the External Purchase Link Entitlement are being introduced to align with the changes to these capabilities.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                          Learn more by visiting Alternative payment options on the App Store in the European Union or request a 30-minute online consultation to ask questions and provide feedback about these changes.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                          Hello Developer: August 2024

                                                                                                                                                                                                                                                                                                                                                                                                                                                                            Meet with Apple

                                                                                                                                                                                                                                                                                                                                                                                                                                                                            Explore the latest developer activities — including sessions, consultations, and labs — all around the world.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                            Browse the full schedule >

                                                                                                                                                                                                                                                                                                                                                                                                                                                                            BEHIND THE DESIGN

                                                                                                                                                                                                                                                                                                                                                                                                                                                                            Creating the make-believe magic of Lost in Play

                                                                                                                                                                                                                                                                                                                                                                                                                                                                            Discover how the developers of this Apple Design Award-winning game conjured up an imaginative world of oversized frogs, mischievous gnomes, and occasional pizzas.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                            Behind the Design: Creating the make-believe magic of Lost in Play View now Get resourceful News snippets

                                                                                                                                                                                                                                                                                                                                                                                                                                                                            SESSION OF THE MONTH

                                                                                                                                                                                                                                                                                                                                                                                                                                                                            Extend your Xcode Cloud workflows

                                                                                                                                                                                                                                                                                                                                                                                                                                                                            Discover how Xcode Cloud can adapt to your development needs.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                            Extend your Xcode Cloud workflows Watch now Subscribe to Hello Developer

                                                                                                                                                                                                                                                                                                                                                                                                                                                                            Want to get Hello Developer in your inbox? Make sure you’ve opted in to receive emails about developer news and events by updating your email preferences in your developer account.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                            Share your thoughts

                                                                                                                                                                                                                                                                                                                                                                                                                                                                            We’d love to hear from you. If you have suggestions for our activities or stories, please let us know.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                            Behind the Design: Creating the make-believe magic of Lost in Play

                                                                                                                                                                                                                                                                                                                                                                                                                                                                              Lost in Play is a game created by and for people who love to play make-believe.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                              The 2024 Apple Design Award (ADA) winner for Innovation is a point-and-click adventure that follows two young siblings, Toto and Gal, through a beautifully animated world of forbidden forests, dark caverns, friendly frogs, and mischievous gnomes. To advance through the game’s story, players complete fun mini-games and puzzles, all of which feel like a Saturday morning cartoon: Before the journey is out, the pair will fetch a sword from a stone, visit a goblin village, soar over the sea on an enormous bird, and navigate the real-world challenges of sibling rivalry. They will also order several pizzas.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                              ADA FACT SHEET

                                                                                                                                                                                                                                                                                                                                                                                                                                                                              Lost in Play
                                                                                                                                                                                                                                                                                                                                                                                                                                                                              • Winner: Innovation
                                                                                                                                                                                                                                                                                                                                                                                                                                                                              • Team: Happy Juice Games, Israel
                                                                                                                                                                                                                                                                                                                                                                                                                                                                              • Available on: iPhone, iPad
                                                                                                                                                                                                                                                                                                                                                                                                                                                                              • Team size: 7
                                                                                                                                                                                                                                                                                                                                                                                                                                                                              • Previous accolades: iPad Game of the Year (2023)

                                                                                                                                                                                                                                                                                                                                                                                                                                                                              Download Lost in Play

                                                                                                                                                                                                                                                                                                                                                                                                                                                                              Learn more about Lost in Play

                                                                                                                                                                                                                                                                                                                                                                                                                                                                              Lost in Play is the brainchild of Happy Juice Games, a small Israel-based team whose three cofounders drew inspiration from their own childhoods — and their own families. “We’ve all watched our kids get totally immersed playing make-believe games,” says Happy Juice’s Yuval Markovich. “We wanted to recreate that feeling. And we came up with the idea of kids getting lost, partly in their imaginations, and partly in real life.”

                                                                                                                                                                                                                                                                                                                                                                                                                                                                              The team was well-equipped for the job. Happy Juice cofounders Markovich, Oren Rubin, and Alon Simon, all have backgrounds in TV and film animation, and knew what they wanted a playful, funny adventure even before drawing their first sketch. “As adults, we can forget how to enjoy simple things like that,” says Simon, “so we set out to make a game about imagination, full of crazy creatures and colorful places.”

                                                                                                                                                                                                                                                                                                                                                                                                                                                                              Toto meets a new friend in the belly of a whale in Lost in Play. At right is an early sketch of the scene.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                              For his part, Markovich didn’t just have a history in gaming; he taught himself English by playing text-based adventure games in the ‘80s. “You played those games by typing ‘go north’ or ‘look around,’ so every time I had to do something, I’d open the dictionary to figure out how to say it,” he laughs. “At some point I realized, ‘Oh wait, I know this language.’”

                                                                                                                                                                                                                                                                                                                                                                                                                                                                              The story became a matter of, ‘OK, a goblin village sounds fun — how do we get there?’

                                                                                                                                                                                                                                                                                                                                                                                                                                                                              Yuval Markovich, Happy Juice Games cofounder

                                                                                                                                                                                                                                                                                                                                                                                                                                                                              But those games could be frustrating, as anyone who ever tried to “leave house” or “get ye flask” can attest. Lost in Play was conceived from day one to be light and navigable. “We wanted to keep it comic, funny, and easy,” says Rubin. “That’s what we had in mind from the very beginning.”

                                                                                                                                                                                                                                                                                                                                                                                                                                                                              Toto must go out on a limb to solve the ravens' puzzle in this screenshot and early sketch.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                              Lost in Play may be a linear experience — it feels closer to playing a movie than a sandbox game — but it’s hardly simple. As befitting a playable dream, its story feels a little unmoored, like it’s being made up on the fly. That’s because the team started with art, characters, and environments, and then went back to add a hero’s journey to the elements.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                              “We knew we’d have a dream in the beginning that introduced a few characters. We knew we’d end up back at the house. And we knew we wanted one scene under the sea, and another in a maker space, and so on,” says Markovich. “The story became a matter of, ‘OK, a goblin village sounds fun — how do we get there?’”

                                                                                                                                                                                                                                                                                                                                                                                                                                                                              Early concept sketches show the character design evolution of Toto and Gal.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                              Naturally, the team drew on their shared backgrounds in animation to shape the game all throughout its three-year development process — and not just in terms of art. Like a lot of cartoons, Lost in Play has no dialogue, both to increase accessibility and to enhance the story’s illusion. Characters speak in a silly gibberish. And there are little cartoon-inspired tricks throughout; for instance, the camera shakes when something is scary. “When you study animation, you also study script writing, cinematography, acting, and everything else,” Markovich says. “I think that’s why I like making games so much: They have everything.”

                                                                                                                                                                                                                                                                                                                                                                                                                                                                              The best thing we hear is that it’s a game parents enjoy playing with their kids.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                              Oren Rubin, Happy Juice games cofounder

                                                                                                                                                                                                                                                                                                                                                                                                                                                                              And in a clever acknowledgment of the realities of childhood, brief story beats return Toto and Gal to the real world to navigate practical issues like sibling rivalries. That’s on purpose: Simon says early versions of the game were maybe a little too cute. “Early on, we had the kids sleeping neatly in their beds,” says Simon. “But we decided that wasn’t realistic. We added a bit more of them picking on each other, and a conflict in the middle of the game.” Still, Markovich says that even the real-world interludes keep one foot in the imaginary world. “They may go through a park where an old lady is feeding pigeons, but then they walk left and there’s a goblin in a swamp,” he laughs.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                              Strange frogs distributing swords are the basis for one of Lost in Play's many inventive puzzles.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                              On the puzzle side, Lost in Play’s mini-games are designed to strike the right level of challenging. The team is especially proud of the game’s system of hints, which often present challenges in themselves. “We didn’t want people getting trapped like I did in those old adventure games,” laughs Markovich. “I loved those, but you could get stuck for months. And we didn’t want people going online to find answers either.” The answer: A hint system that doesn’t just hand over the answer but gives players a feeling of accomplishment, an incentive to go back for more.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                              It all adds up to a unique experience for players of all ages — and that’s by design too. “The best feedback we get is that it’s suitable for all audiences,” says Rubin, “and the best thing we hear is that it’s a game parents enjoy playing with their kids.”

                                                                                                                                                                                                                                                                                                                                                                                                                                                                              Meet the 2024 Apple Design Award winners

                                                                                                                                                                                                                                                                                                                                                                                                                                                                              Behind the Design is a series that explores design practices and philosophies from finalists and winners of the Apple Design Awards. In each story, we go behind the screens with the developers and designers of these award-winning apps and games to discover how they brought their remarkable creations to life.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                              Updates to runtime protection in macOS Sequoia

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                In macOS Sequoia, users will no longer be able to Control-click to override Gatekeeper when opening software that isn’t signed correctly or notarized. They’ll need to visit System Settings > Privacy & Security to review security information for software before allowing it to run.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                If you distribute software outside of the Mac App Store, we recommend that you submit your software to be notarized. The Apple notary service automatically scans your Developer ID-signed software and performs security checks. When your software is ready for distribution, it’s assigned a ticket to let Gatekeeper know it’s been notarized so customers can run it with confidence.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                Learn how to notarize your macOS software

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                Updated guidelines now available

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  The App Review Guidelines have been revised to support updated policies and upcoming features, and to provide clarification.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  • Updated 4.7 to clarify that PC emulator apps can offer to download games.
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  • Added 4.7, 4.7.2, and 4.7.3 to Notarization.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  View the App Review Guidelines

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  Get resources and support to prepare for App Review

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  Translations of the guidelines will be available on the Apple Developer website within one month.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  Hello Developer: July 2024

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    Dive into all the new updates from WWDC24

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    Our doors are open. Join us to explore all the new sessions, documentation, and features through online and in-person activities held in 15 cities around the world.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    Sign up now >

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    Join us July 22–26 for online office hours to get one-on-one guidance about your app or game. And visit the forums where more engineers are ready to answer your questions.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    Reserve your spot >

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    Browse the forums >

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    WWDC24 highlights View now

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    BEHIND THE DESIGN

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    Positive vibrations: How Gentler Streak approaches fitness with “humanity”

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    Find out why the team behind this Apple Design Award-winning lifestyle app believes success is about more than stats.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    Behind the Design: How Gentler Streak approaches fitness with “humanity“ View now

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    GET RESOURCEFUL

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    New sample code New in the HIG
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    • Design for games: Make your game feel at home on all Apple devices.
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    • Take control of controls: Provide quick access to a feature of your app from Control Center, the Lock Screen, or the Action button.
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    • Tint your icons: Create dark and tinted app icon variants for iOS and iPadOS.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    SESSION OF THE MONTH

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    Say hello to the next generation of CarPlay design system

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    Learn how the system at the heart of CarPlay allows each automaker to express their vehicle’s character and brand.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    Say hello to the next generation of CarPlay design system Watch now Subscribe to Hello Developer

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    Want to get Hello Developer in your inbox? Make sure you’ve opted in to receive emails about developer news and events by updating your email preferences in your developer account.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    Share your thoughts

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    We’d love to hear from you. If you have suggestions for our activities or stories, please let us know.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    Behind the Design: How Gentler Streak approaches fitness with “humanity“

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      Gentler Streak is a different kind of fitness tracker. In fact, to hear cofounder and CEO Katarina Lotrič tell it, it’s not really a fitness tracker at all.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      “We think of it more as a lifestyle app,” says Lotrič, from the team’s home office in Kranj, Slovenia. “We want it to feel like a compass, a reminder to get moving, no matter what that means for you,” she says.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      ADA FACT SHEET

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      The app’s “Go Gentler” page suggests optimal workouts for a user’s day.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      Gentler Streak
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      • Winner: Social Impact
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      • Team: Gentler Stories d.o.o., Slovenia
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      • Available on: iPhone, iPad, Apple Watch
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      • Team size: 8
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      • Previous accolades: Apple Watch App of the Year (2022), Apple Design Award finalist (Visuals and graphics, 2023)

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      Download Gentler Streak from the App Store

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      Learn more about Gentler Streak

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      Meet the 2024 Apple Design Award winners

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      That last part is key. True to its name, the Apple Design Award-winning Gentler Streak takes a friendlier approach to fitness. Instead of focusing on performance — on the bigger, faster, and stronger — Gentler Streak meets people where they are, presenting workout suggestions, statistics, and encouragement for all skill levels.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      “A lot of mainstream fitness apps can seem to be about pushing all the time,” Lotrič says. “But for a lot of people, that isn’t the reality. Everyone has different demands and capabilities on different days. We thought, ‘Can we create a tool to help anyone know where they’re at on any given day, and guide them to a sustainably active lifestyle?’”

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      If a 15-minute walk is what your body can do at that moment, that’s great.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      Katarina Lotrič, CEO and cofounder of Gentler Stories

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      To reach those goals, Lotrič and her Gentler Stories cofounders — UI/UX designer Andrej Mihelič, senior developer Luka Orešnik, and CTO and iOS developer Jasna Krmelj — created an app powered by an optimistic and encouraging vibe that considers physical fitness and mental well-being equally.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      Fitness and workout data (collected from HealthKit) is presented in a colorful, approachable design. The app’s core functions are available for free; a subscription unlocks premium features. And an abstract mascot named Yorhart (sound it out) adds to the light touch. “Yorhart helps you establish a relationship with the app and with yourself, because it’s what your heart would be telling you,” Lotrič says.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      Good news from Yorhart: This user’s needs and capabilities are being met perfectly.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      It’s working: In addition to the 2024 Apple Design Award for Social Impact, Gentler Streak was named 2022 Apple Watch App of the Year. What’s more, it has an award-winning ancestor: Lotrič and Orešnik won an Apple Design Award in 2017 for Lake: Coloring Book for Adults.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      The trio used the success of Lake to learn more about navigating the industry. But something else was happening during that time: The team, all athletes, began revisiting their own relationships with fitness. Lotrič suffered an injury that kept her from running for months and affected her mental health; she writes about her experiences in Gentler Streak’s editorial section. Mihelič had a different issue. “My problem wasn’t that I lacked motivation,” he says. “It was that I worked out too much. I needed something that let me know when it was enough.”

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      Statistics are just numbers. Without knowing how to interpret them, they are meaningless.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      Katarina Lotrič, CEO and cofounder of Gentler Stories

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      As a way to reset, Mihelič put together an internal app, a simple utility that encouraged him to move but also allowed time for recuperation. “It wasn’t very gentle,” he laughs. “But the core idea was more or less the same. It guided but it didn’t push. And it wasn’t based on numbers; it was more explanatory.”

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      Over time, the group began using Mihelič’s app. “We saw right away that it was sticky,” says Lotrič. “I came back to it daily, and it was just this basic prototype. After a while, we realized, ‘Well, this works and is built, to an extent. Why don’t we see if there’s anything here?’”

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      Gentler Streak pulls workout information from HealthKit and presents it in simple, easy-to-understand charts.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      That’s when Lotrič, Orešnik, and Krmelj split from Lake to create Gentler Stories with Mihelič. "I wanted in because I loved the idea behind the whole company,” Krmelj says. “It wasn’t just about the app. I really like the app. But I really believed in this idea about mental well-being.”

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      Early users believed it too: The team found that initial TestFlight audience members returned at a stronger rate than expected. “Our open and return rates were high enough that we kept thinking, “Are these numbers even real?’” laughs Lotrič. The team found that those early users responded strongly to the “gentler” side, the approachable repositioning of statistics.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      “We weren’t primarily addressing the audience that most fitness apps seemed to target,” says Lotrič. “We focused on everyone else, the people who maybe didn’t feel like they belonged in a gym. Statistics are just numbers. Without knowing how to interpret them, they are meaningless. We wanted to change that and focus on the humanity.” By fall of 2021, Gentler Streak was ready for prime time.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      Gentler Streak on Apple Watch brings encouragement closer than ever before.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      Today’s version of the app follows the same strategy of Mihelič’s original prototype. Built largely in UIKit, its health data is smartly organized, the design is friendly and consistent, and features like its Monthly Summary view — which shows how you’re doing in relation to your history — focus less on comparison and more on progress, whatever that may mean. “If a 15-minute walk is what your body can do at that moment, that’s great,” Lotrič says. “That how we make people feel represented.”

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      The app’s social impact continues to grow. In the spring of 2024, Gentler Streak added support for Japanese, Korean, and traditional and simplified Chinese languages; previous updates added support for French, German, Italian, Spanish, and Brazilian Portuguese.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      And those crucial features — fitness tracking, workout suggestions, metrics, and activity recaps — will remain available to everyone. “That goes with the Gentler Stories philosophy,” says Lotrič. “We’re bootstrapped, but at the same time we know that not everyone is in a position to support us. We still want to be a tool that helps people stay healthy not just for the first two weeks of the year or the summer, but all year long.”

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      Meet the 2024 Apple Design Award winners

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      Behind the Design is a series that explores design practices and philosophies from finalists and winners of the Apple Design Awards. In each story, we go behind the screens with the developers and designers of these award-winning apps and games to discover how they brought their remarkable creations to life.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      Alternative payment options in the EU in visionOS 1.2

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        Alternative payment options are now supported starting in visionOS 1.2 for apps distributed on the App Store in the EU.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        Learn about alternative payments in the EU

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        Changes for apps in the EU now available in iPadOS 18 beta 2

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          The changes for apps in the European Union (EU), currently available to iOS users in the 27 EU member countries, can now be tested in iPadOS 18 beta 2 with Xcode 16 beta 2.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          Also, the Web Browser Engine Entitlement Addendum for Apps in the EU and Embedded Browser Engine Entitlement Addendum for Apps in the EU now include iPadOS. If you’ve already entered into either of these addendums, be sure to sign the updated terms.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          Learn more about the recent changes:

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          The App Store on Apple Vision Pro expands to new markets

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            Apple Vision Pro will launch in China mainland, Hong Kong, Japan, and Singapore on June 28 and in Australia, Canada, France, Germany, and the United Kingdom on July 12. Your apps and games will be automatically available on the App Store in regions you’ve selected in App Store Connect.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            If you’d like, you can:

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            You can also learn how to build native apps to fully take advantage of exciting visionOS features.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            Upcoming regional age ratings in Australia and South Korea

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              Apple is committed to making sure that the App Store is a safe place for everyone — especially kids. Within the next few months, you’ll need to indicate in App Store Connect if your app includes loot boxes available for purchase. In addition, a regional age rating based on local laws will automatically appear on the product page of the apps listed below on the App Store in Australia and South Korea. No other action is needed. Regional age ratings appear in addition to Apple global age ratings.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              Australia

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              A regional age rating is shown if Games is selected as the primary or secondary category in App Store Connect.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              • 15+ regional age rating: Games with loot boxes available for purchase.
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              • 18+ regional age rating: Games with Frequent/Intense instances of Simulated Gambling indicated in App Store Connect.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              South Korea

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              A regional age rating is shown if either Games or Entertainment is selected as the primary or secondary category in App Store Connect, or if the app has Frequent/Intense instances of Simulated Gambling in any category.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              • KR-All regional age rating: Apps and games with an Apple global age rating of 4+ or 9+.
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              • KR-12 regional age rating: Apps and games with an Apple global age rating of 12+. Certain apps and games in this group may receive a KR-15 regional age rating from the South Korean Games Ratings and Administration Committee (GRAC). If this happens, App Review will reach out to impacted developers.
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              • Certain apps and games may receive a KR-19 regional age rating from the GRAC. Instead of a pictogram, text will indicate this rating.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              WWDC24 resources and survey

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                Thank you to everyone who joined us for an amazing week. We hope you found value, connection, and fun. You can continue to:

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                We’d love to know what you thought of this year’s conference. If you’d like to tell us about your experience, please complete the WWDC24 survey.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                Take the survey

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                WWDC24 highlights

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  Browse the biggest moments from an incredible week of sessions.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  Machine Learning & AI Explore machine learning on Apple platforms Watch now Bring expression to your app with Genmoji Watch now Get started with Writing Tools Watch now Bring your app to Siri Watch now Design App Intents for system experiences Watch now Swift What’s new in Swift Watch now Meet Swift Testing Watch now Migrate your app to Swift 6 Watch now Go small with Embedded Swift Watch now SwiftUI & UI Frameworks What’s new in SwiftUI Watch now SwiftUI essentials Watch now Enhance your UI animations and transitions Watch now Evolve your document launch experience Watch now Squeeze the most out of Apple Pencil Watch now Developer Tools What’s new in Xcode 16 Watch now Extend your Xcode Cloud workflows Watch now Spatial Computing Design great visionOS apps Watch now Design interactive experiences for visionOS Watch now Explore game input in visionOS Watch now Bring your iOS or iPadOS game to visionOS Watch now Create custom hover effects in visionOS Watch now Work with windows in SwiftUI Watch now Dive deep into volumes and immersive spaces Watch now Customize spatial Persona templates in SharePlay Watch now Design Design great visionOS apps Watch now Design interactive experiences for visionOS Watch now Design App Intents for system experiences Watch now Design Live Activities for Apple Watch Watch now Say hello to the next generation of CarPlay design system Watch now Add personality to your app through UX writing Watch now Graphics & Games Port advanced games to Apple platforms Watch now Design advanced games for Apple platforms Watch now Bring your iOS or iPadOS game to visionOS Watch now Meet TabletopKit for visionOS Watch now App Store Distribution and Marketing What’s new in StoreKit and In-App Purchase Watch now What’s new in App Store Connect Watch now Implement App Store Offers Watch now Privacy & Security Streamline sign-in with passkey upgrades and credential managers Watch now What’s new in privacy Watch now App and System Services Meet the Contact Access Button Watch now Use CloudKit Console to monitor and optimize database activity Watch now Extend your app’s controls across the system Watch now Safari & Web Optimize for the spatial web Watch now Build immersive web experiences with WebXR Watch now Accessibility & Inclusion Catch up on accessibility in SwiftUI Watch now Get started with Dynamic Type Watch now Build multilingual-ready apps Watch now Photos & Camera Build a great Lock Screen camera capture experience Watch now Build compelling spatial photo and video experiences Watch now Keep colors consistent across captures Watch now Use HDR for dynamic image experiences in your app Watch now Audio & Video Enhance the immersion of media viewing in custom environments Watch now Explore multiview video playback in visionOS Watch now Build compelling spatial photo and video experiences Watch now Business & Education Introducing enterprise APIs for visionOS Watch now What’s new in device management Watch now Health & Fitness Explore wellbeing APIs in HealthKit Watch now Build custom swimming workouts with WorkoutKit Watch now Get started with HealthKit in visionOS Watch now

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  Today @ WWDC24: Day 5

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    Revisit the biggest moments from WWDC24

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    Explore the highlights.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    WWDC24 highlights View now Catch WWDC24 recaps around the world

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    Join us for special in-person activities at Apple locations worldwide this summer.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    Sign up >

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    Explore apps and games from the Keynote

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    Check out all the incredible featured titles.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    Visit the App Store >

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    How’d we do?

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    We’d love to know your thoughts about this year’s conference.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    Take the survey >

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    Today’s WWDC24 playlist: Power Up

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    Get ready for one last day.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    Listen on Apple Music >

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    And that’s a wrap!

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    Thanks for being part of another incredible WWDC. It’s been a fantastic week of celebrating, connecting, and exploring, and we appreciate the opportunity to share it all with you.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    Today @ WWDC24: Day 4

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      Plan for platforms

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      Find out what’s new across Apple platforms.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      Design great visionOS apps Watch now Bring your iOS or iPadOS game to visionOS Watch now Design App Intents for system experiences Watch now Explore all platforms sessions Guides

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      Sessions, labs, documentation, and sample code — all in one place.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      WWDC24 iOS & iPadOS guide View now WWDC24 Games guide View now WWDC24 visionOS guide View now WWDC24 watchOS guide View now Today’s WWDC24 playlist: Coffee Shop

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      Comfy acoustic sounds for quieter moments.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      Listen on Apple Music >

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      One more to go

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      What a week! But we’re not done yet — we’ll be back tomorrow for a big Friday. #WWDC24

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      Today @ WWDC24: Day 3

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        All Swift, all day

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        Explore new Swift and SwiftUI sessions.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        What’s new in Swift Watch now What’s new in SwiftUI Watch now Meet Swift Testing Watch now Explore all Swift sessions Guides

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        Sessions, labs, documentation, and sample code — all in one place.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        WWDC24 Swift guide View now WWDC24 Developer Tools guide View now WWDC24 SwiftUI & UI Frameworks guide View now Go further with Swift

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        Connect with Apple experts and the worldwide developer community.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        Today’s WWDC24 playlist: A jazz thing

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        Cutting-edge sounds from the global frontiers of jazz.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        Listen on Apple Music >

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        More to come

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        Thanks for being a part of #WWDC24. We’ll be back tomorrow with even more.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        Today @ WWDC24: Day 2

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          Watch the Platforms State of the Union 5-minute recap

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          Explore everything announced at WWDC24 >

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          Introducing Apple Intelligence

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          Get smarter.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          Explore machine learning on Apple platforms Watch now Get started with Writing Tools Watch now Bring your app to Siri Watch now Explore all Machine Learning and AI sessions Guides

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          Sessions, labs, documentation, and sample code — all in one place.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          WWDC24 Machine Learning & AI guide View now WWDC24 Design guide View now Go further with Apple Intelligence Today’s WWDC24 playlist: Hello sunshine

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          Summer sounds to change your latitude.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          Listen on Apple Music >

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          More tomorrow

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          Thanks for being a part of this incredible week. We’ll catch you tomorrow for another big day of technology and creativity. #WWDC24

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          Find out what’s new and download beta releases

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            Discover the latest advancements across Apple platforms, including the all-new Apple Intelligence, that can help you create even more powerful, intuitive, and unique experiences.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            To start exploring and building with the latest features, download beta versions of Xcode 16, iOS 18, iPadOS 18, macOS 15, tvOS 18, visionOS 2, and watchOS 11.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            Learn about installing beta software

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            Learn about sharing feedback

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            Explore new documentation and sample code from WWDC24

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              Browse new and updated documentation and sample code to learn about the latest technologies, frameworks, and APIs introduced at WWDC24.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              Explore everything announced at WWDC24 >

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              WWDC24 Design guide

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                WWDC24 GUIDE Design

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                Discover how this year’s design announcements can help make your app shine on Apple platforms.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                Whether you’re refining your design, building for visionOS, or starting from scratch, this year’s design sessions can take your app to the next level on Apple platforms. Find out what makes a great visionOS app, and learn how to design interactive experiences for the spatial canvas. Dive into creating advanced games for Apple devices, explore the latest SF Symbols, learn how to add personality to your app through writing, and much more.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                Get the highlights

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                Download the design one-sheet.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                Download

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                VIDEOS

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                Explore the latest video sessions Design great visionOS apps Watch now Design advanced games for Apple platforms Watch now Create custom environments for your immersive apps in visionOS Watch now Explore game input in visionOS Watch now Design Live Activities for Apple Watch Watch now What’s new in SF Symbols 6 Watch now Design interactive experiences for visionOS Watch now Design App Intents for system experiences Watch now Build multilingual-ready apps Watch now Add personality to your app through UX writing Watch now Get started with Dynamic Type Watch now Create custom visual effects with SwiftUI Watch now

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                FORUMS

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                Find answers and get advice

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                Ask questions and get advice about design topics on the Apple Developer Forums.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                Design

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                Spatial computing

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                COMMUNITY

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                Meet the community

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                Explore a selection of developer activities all over the world during and after WWDC.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                Meet the community

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                RESOURCES

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                Explore the latest resources Check out updates to the Human Interface Guidelines
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                • Find out all that’s new in the HIG.
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                • Designing for games: Explore an all-new way to start creating games that feel comfortable and intuitive on Apple platforms.
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                • Tab bars: iPadOS apps now give people the option to switch between a tab bar or sidebar when navigating their app. Plus, items in the tab bar can now be customized.
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                • App icons: Learn how people can customize their Home Screens to show dark and tinted icons.
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                • Controls: Discover how people can quickly and easily perform actions from your app from Control Center, the Lock Screen, and the Action button.
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                • Widgets: Learn how to tint widgets when a person has customized their Home Screen to show dark and tinted icons.
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                • Windows: Learn how to use volumes in visionOS to display 2D or 3D content that people can view from any angle.
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                • Live Activities: Craft Live Activities that look and feel at home in the Smart Stack in watchOS.
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                • Immersive experiences: Explore the latest guidance on immersion, including design environments and virtual hands.
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                • Game controls: Learn how to design touch controls for games on iOS and iPadOS.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                WWDC24 Swift guide

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  WWDC24 GUIDE Swift

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  Your guide to everything new in Swift, related tools, and supporting frameworks.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  From expanded support across platforms and community resources, to an optional language mode with an emphasis on data-race safety, this year’s Swift updates meet you where you are. Explore this year’s video sessions to discover everything that’s new in Swift 6, find tools that support migrating to the new language mode at your own pace, learn about new frameworks that support developing with Swift, and much more.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  Get the highlights

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  Download the Swift one-sheet.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  Download

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  VIDEOS

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  Explore the latest video sessions What’s new in Swift Watch now What’s new in SwiftData Watch now Migrate your app to Swift 6 Watch now Go small with Embedded Swift Watch now A Swift Tour: Explore Swift’s features and design Watch now Create a custom data store with SwiftData Watch now Explore the Swift on Server ecosystem Watch now Explore Swift performance Watch now Consume noncopyable types in Swift Watch now Track model changes with SwiftData history Watch now

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  FORUMS

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  Find answers and get advice

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  Find support from Apple experts and the developer community on the Apple Developer Forums, and check out the Swift Forums on swift.org.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  Explore Swift on the Apple Developer Forums

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  Dive into the Swift Forums

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  COMMUNITY

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  Meet the community

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  Explore a selection of activities hosted by developer organizations during and after WWDC.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  Meet the community

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  RESOURCES

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  Dive into Apple Developer documentation Discover Swift community resources

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  WWDC24 SwiftUI &amp; UI Frameworks guide

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    WWDC24 GUIDE SwiftUI & UI Frameworks

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    Design and build your apps like never before.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    With enhancements to live previews in Xcode, new customization options for animations and styling, and updates to interoperability with UIKit and AppKit views, SwiftUI is the best way to build apps for Apple platforms. Dive into the latest sessions to discover everything new in SwiftUI, UIKit, AppKit, and more. Make your app stand out with more options for custom visual effects and enhanced animations. And explore sessions that cover the essentials of building apps with SwiftUI.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    Get the highlights

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    Download the SwiftUI one-sheet.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    Download

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    VIDEOS

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    Explore the latest video sessions What’s new in SwiftUI Watch now What’s new in AppKit Watch now What’s new in UIKit Watch now SwiftUI essentials Watch now What’s new in watchOS 11 Watch now Swift Charts: Vectorized and function plots Watch now Elevate your tab and sidebar experience in iPadOS Watch now Bring expression to your app with Genmoji Watch now Squeeze the most out of Apple Pencil Watch now Catch up on accessibility in SwiftUI Watch now Migrate your TVML app to SwiftUI Watch now Get started with Writing Tools Watch now Dive deep into volumes and immersive spaces Watch now Work with windows in SwiftUI Watch now Enhance your UI animations and transitions Watch now Evolve your document launch experience Watch now Build multilingual-ready apps Watch now Create custom hover effects in visionOS Watch now Tailor macOS windows with SwiftUI Watch now Demystify SwiftUI containers Watch now Support semantic search with Core Spotlight Watch now Create custom visual effects with SwiftUI Watch now

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    FORUMS

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    Find answers and get advice

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    Connect with Apple experts and other developers on the Apple Developer Forums.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    View discussions about SwiftUI & UI frameworks

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    COMMUNITY

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    Meet the community

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    Explore a selection of activities hosted by developer organizations during and after WWDC.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    Meet the community

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    RESOURCES

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    Dive into documentation

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    Today @ WWDC24: Day 1

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      It all starts here

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      Keynote

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      The exciting reveal of the latest Apple software and technologies. 10 a.m. PT.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      Keynote Watch now

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      Platforms State of the Union

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      The newest advancements on Apple platforms. 1 p.m. PT.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      Platforms State of the Union Watch now

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      Where to watch

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      Sessions drop today

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      The full lineup of sessions arrives after the Keynote. And you can start exploring the first batch right after the Platforms State of the Union.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      Get ready for sessions >

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      What to do at WWDC24

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      The Keynote is only the beginning. Explore the first day of activities.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      Celebrate the 2024 Apple Design Award winners

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      The Apple Design Awards recognize unique achievements in app and game design — and provide a moment to step back and celebrate the innovations of the Apple developer community.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      Meet this year’s winners >

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      More to come

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      Thanks for reading and get some rest! We’ll be back tomorrow for a very busy Day 2. #WWDC24

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      WWDC24 Developer Tools guide

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        WWDC24 GUIDE Developer Tools

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        Explore a wave of updates to developer tools that make building apps and games easier and more efficient than ever.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        Watch the latest video sessions to explore a redesigned code completion experience in Xcode 16, and say hello to Swift Assist — a companion for all your coding tasks. Level up your code with the help of Swift Testing, the new, easy-to-learn framework that leverages Swift features to help enhance your testing experience. Dive deep into debugging, updates to Xcode Cloud, and more.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        Get the highlights

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        Download the developer tools one-sheet.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        Download

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        VIDEOS

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        Explore the latest video sessions Meet Swift Testing Watch now What’s new in Xcode 16 Watch now Go further with Swift Testing Watch now Xcode essentials Watch now Run, Break, Inspect: Explore effective debugging in LLDB Watch now Break into the RealityKit debugger Watch now Demystify explicitly built modules Watch now Extend your Xcode Cloud workflows Watch now Analyze heap memory Watch now

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        FORUMS

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        Find answers and get advice

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        Find support from Apple experts and the developer community on the Apple Developer Forums.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        Explore developer tools on the forums

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        COMMUNITY

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        Meet the community

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        Explore a selection of activities hosted by developer organizations during and after WWDC.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        Meet the community

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        RESOURCES

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        Dive into documentation

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        Expand your tool belt with new and updated articles and documentation.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        WWDC24 iOS &amp; iPadOS guide

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          WWDC24 GUIDE iOS & iPadOS

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          Your guide to all the new features and tools for building apps for iPhone and iPad.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          Learn how to create more customized and intelligent apps that appear in more places across the system with the latest Apple technologies. And with Apple Intelligence, you can bring personal intelligence into your apps to deliver new capabilities — all with great performance and built-in privacy. Explore new video sessions about controls, Live Activities, App Intents, and more.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          Get the highlights

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          Download the iOS & iPadOS one-sheet.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          Download

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          VIDEOS

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          Explore the latest video sessions Bring your app to Siri Watch now Discover RealityKit APIs for iOS, macOS, and visionOS Watch now Explore machine learning on Apple platforms Watch now Elevate your tab and sidebar experience in iPadOS Watch now Extend your app’s controls across the system Watch now Streamline sign-in with passkey upgrades and credential managers Watch now What’s new in App Intents Watch now Squeeze the most out of Apple Pencil Watch now Meet FinanceKit Watch now Bring your iOS or iPadOS game to visionOS Watch now Build a great Lock Screen camera capture experience Watch now Design App Intents for system experiences Watch now Bring your app’s core features to users with App Intents Watch now Broadcast updates to your Live Activities Watch now Unlock the power of places with MapKit Watch now Implement App Store Offers Watch now What’s new in Wallet and Apple Pay Watch now Meet the Contact Access Button Watch now What’s new in device management Watch now

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          FORUMS

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          Find answers and get advice

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          Connect with Apple experts and other developers on the Apple Developer Forums.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          View discussions about iOS

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          View discussions about iPadOS

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          COMMUNITY

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          Meet the community

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          Explore a selection of activities hosted by developer organizations during and after WWDC.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          Meet the community

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          RESOURCES

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          Get a head start with sample code Dive into documentation

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          WWDC24 Machine Learning &amp; AI guide

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            WWDC24 GUIDE Machine Learning & AI

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            Bring personal intelligence to your apps.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            Apple Intelligence brings powerful, intuitive, and integrated personal intelligence to Apple platforms — designed with privacy from the ground up. And enhancements to our machine learning frameworks let you run and train your machine learning and artificial intelligence models on Apple devices like never before.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            Get the highlights

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            Download the Machine Learning & AI one-sheet.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            Download

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            VIDEOS

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            Explore the latest video sessions

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            Get the most out of Apple Intelligence by diving into sessions that cover updates to Siri integration and App Intents, and how to support Writing Tools and Genmoji in your app. And learn how to bring machine learning and AI directly into your apps using our machine learning frameworks.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            Explore machine learning on Apple platforms Watch now Bring your app to Siri Watch now Bring your app’s core features to users with App Intents Watch now Bring your machine learning and AI models to Apple silicon Watch now Get started with Writing Tools Watch now Deploy machine learning and AI models on-device with Core ML Watch now Support real-time ML inference on the CPU Watch now Bring expression to your app with Genmoji Watch now What’s new in App Intents Watch now What’s new in Create ML Watch now Design App Intents for system experiences Watch now Discover Swift enhancements in the Vision framework Watch now Meet the Translation API Watch now Accelerate machine learning with Metal Watch now Train your machine learning and AI models on Apple GPUs Watch now

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            FORUMS

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            Find answers and get advice

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            Connect with Apple experts and other developers on the Apple Developer Forums.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            Dive into Machine learning and AI on the forums

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            COMMUNITY

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            Meet the community

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            Explore a selection of activities hosted by developer organizations during and after WWDC.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            Meet the community

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            RESOURCES

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            Dive into documentation

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            WWDC24 Games guide

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              WWDC24 GUIDE Games

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              Create the next generation of games for millions of players worldwide.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              Learn how to create cutting-edge gaming experiences across a unified gaming platform built with tightly integrated graphics software and a scalable hardware architecture. Explore new video sessions about gaming in visionOS, game input, the Game Porting Toolkit 2, and more.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              Get the highlights

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              Download the games one-sheet.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              Download

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              VIDEOS

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              Explore the latest video sessions Render Metal with passthrough in visionOS Watch now Meet TabletopKit for visionOS Watch now Port advanced games to Apple platforms Watch now Design advanced games for Apple platforms Watch now Explore game input in visionOS Watch now Bring your iOS or iPadOS game to visionOS Watch now Accelerate machine learning with Metal Watch now

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              FORUMS

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              Find answers and get advice

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              Connect with Apple experts and other developers on the Apple Developer Forums.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              View discussions about games

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              COMMUNITY

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              Meet the community

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              Explore a selection of activities hosted by developer organizations during and after WWDC.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              Meet the community

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              RESOURCES

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              Get a head start with sample code Dive into documentation

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              WWDC24 watchOS guide

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                WWDC24 GUIDE watchOS

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                Your guide to all the new features and tools for building apps for Apple Watch.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                Learn how to take advantage of the increased intelligence and capabilities of the Smart Stack. Explore new video sessions about relevancy cues, interactivity, Live Activities, and double tap.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                Get the highlights

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                Download the watchOS one-sheet.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                Download

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                VIDEOS

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                Explore the latest video sessions What’s new in watchOS 11 Watch now Bring your Live Activity to Apple Watch Watch now What’s new in SwiftUI Watch now SwiftUI essentials Watch now Design Live Activities for Apple Watch Watch now Catch up on accessibility in SwiftUI Watch now Build custom swimming workouts with WorkoutKit Watch now Demystify SwiftUI containers Watch now

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                FORUMS

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                Find answers and get advice

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                Connect with Apple experts and other developers on the Apple Developer Forums.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                View discussions about watchOS

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                COMMUNITY

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                Meet the community

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                Explore a selection of activities hosted by developer organizations during and after WWDC.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                Meet the community

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                RESOURCES

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                Dive into documentation

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                WWDC24 sessions schedule, lab requests, guides, and documentation now available

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  WWDC24 is here! Here’s how to make the most of your week:

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  • Watch daily sessions.
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  • Request one-on-one online lab appointments with Apple experts.
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  • Check out curated guides to the week’s biggest announcements.
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  • Dive into new and updated documentation.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  Learn more

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  WWDC24 visionOS guide

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    WWDC24 GUIDE visionOS

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    The infinite canvas is waiting for you.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    In this year’s sessions, you’ll get an overview of great visionOS app design, explore object tracking, and discover new RealityKit APIs. You’ll also find out how to build compelling spatial photo and video experiences, explore enterprise APIs for visionOS, find out how to render Metal with passthrough, and much more.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    Get the highlights

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    Download the visionOS one-sheet.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    Download

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    VIDEOS

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    Explore the latest video sessions Design great visionOS apps Watch now Explore object tracking for visionOS Watch now Compose interactive 3D content in Reality Composer Pro Watch now Discover RealityKit APIs for iOS, macOS, and visionOS Watch now Create enhanced spatial computing experiences with ARKit Watch now Enhance your spatial computing app with RealityKit audio Watch now Build compelling spatial photo and video experiences Watch now Meet TabletopKit for visionOS Watch now Render Metal with passthrough in visionOS Watch now Explore multiview video playback in visionOS Watch now Introducing enterprise APIs for visionOS Watch now Dive deep into volumes and immersive spaces Watch now Build a spatial drawing app with RealityKit Watch now Optimize for the spatial web Watch now Explore game input in visionOS Watch now Create custom environments for your immersive apps in visionOS Watch now Enhance the immersion of media viewing in custom environments Watch now Design interactive experiences for visionOS Watch now Create custom hover effects in visionOS Watch now Optimize your 3D assets for spatial computing Watch now Discover area mode for Object Capture Watch now Bring your iOS or iPadOS game to visionOS Watch now Build immersive web experiences with WebXR Watch now Get started with HealthKit in visionOS Watch now What’s new in Quick Look for visionOS Watch now What’s new in USD and MaterialX Watch now Customize spatial Persona templates in SharePlay Watch now Create enhanced spatial computing experiences with ARKit Watch now Break into the RealityKit debugger Watch now What’s new in SwiftUI Watch now

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    FORUMS

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    Find answers and get advice

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    Connect with Apple experts and other developers on the Apple Developer Forums.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    View discussions about visionOS

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    COMMUNITY

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    Meet the community

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    Explore a selection of activities hosted by developer organizations during and after WWDC.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    Meet the community

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    RESOURCES

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    Get a head start with sample code Dive into documentation

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    Updated agreements and guidelines now available

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      The App Review Guidelines, Apple Developer Program License Agreement, and Apple Developer Agreement have been updated to support updated policies and upcoming features, and to provide clarification. Please review the changes below and accept the updated terms as needed.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      App Review Guidelines
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      • 2.1(a): Added to Notarization.
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      • 2.1(b): Added requirement to explain why configured in-app items cannot be found or reviewed in your app to your review notes.
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      • 2.5.8: We will no longer reject apps that simulate multi-app widget experiences.
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      • 4.6: This guideline has been removed.
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      Apple Developer Agreement
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      • Sections 1, 6(B): Updated “Apple ID” to “Apple Account.”
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      • Section 16(A): Clarified export compliance requirements.
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      • Section 18: Updated terminology for government end users.
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      Developer Program License Agreement
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      • Definitions, Section 2.1, 3.3.6(C), 3.3.10(A), 14.2(C), Attachment 9, Schedules 1-3: Updated “Apple ID” to “Apple Account.”
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      • Definitions: Clarified definition of Apple Maps Service.
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      • Definitions, Section 3.3.6(F): Specified requirements for using the Apple Music Feed API.
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      • Definitions, Section 3.3.8(F): Added terms for use of the Now Playing API.
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      • Section 3.2(h): Added terms for use of Apple Software and Services.
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      • Section 6.5: Added terms for use of TestFlight.
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      • Section 7.7: Added terms on customization of icons.
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      • Section 11.2(f), 14.8(A): Clarified export compliance requirements.
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      • Section 14.9: Updated terminology for government end users.
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      • Attachment 5, Section 3.1: Added terms for use of Wallet pass templates.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      Please sign in to your account to review and accept the updated terms.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      View all agreements and guidelines

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      Translations of the terms will be available on the Apple Developer website within one month.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      Hello Developer: June 2024

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        With WWDC24 just days away, there’s a lot of ground to cover, so let’s get right to it.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        WWDC24

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        Introducing the 2024 Apple Design Award winners

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        Innovation. Ingenuity. Inspiration.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        Meet this year’s winners >

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        WWDC24: Everything you need to know

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        From the Keynote to the last session drop, here are the details for an incredible week of sessions, labs, community activities, and more.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        Download the Apple Developer app >

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        Subscribe to Apple Developer on YouTube >

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        Watch the Keynote

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        Don’t miss the exciting reveal of the latest Apple software and technologies at 10 a.m. PT on Monday, June 10.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        Add to calendar >

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        Watch the Platforms State of the Union

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        Here’s your deep dive into the newest advancements on Apple platforms. Join us at 1 p.m. PT on Monday, June 10.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        Add to calendar >

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        Get ready for sessions

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        Learn something new in video sessions posted to the Apple Developer app, website, and YouTube channel. The full schedule drops after the Keynote on Monday, June 10.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        Learn more >

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        Prepare for labs

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        Here’s everything you need to know to get ready for online labs.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        Read more >

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        Find answers on the forums

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        Discuss the conference’s biggest moments on the Apple Developer Forums.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        Join the conversation >

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        Get the most out of the forums >

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        Meet the community

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        Explore a selection of activities hosted by developer organizations during and after WWDC.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        Explore community activities >

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        Say hello to the first WWDC24 playlist

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        The official WWDC24 playlists drop right after the Keynote. Until then, here’s a teaser playlist to get you excited for the week.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        Listen on Apple Music >

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        Coming up: One incredible week

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        Have a great weekend, and we’ll catch you on Monday. #WWDC24

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        Watch the WWDC24 Keynote

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          WWDC24

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          Tune in at 10 a.m. PT on June 10 to catch the exciting reveal of the latest Apple software and technologies.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          Keynote Watch now Keynote (ASL) Watch now

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          Watch the WWDC24 Platforms State of the Union

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            WWDC24

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            Tune in at 1 p.m. PT on June 10 to dive deep into the newest advancements on Apple platforms.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            Platforms State of the Union Watch now Platforms State of the Union (ASL) Watch now

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            Price and tax updates for apps, In-App Purchases, and subscriptions

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              The App Store is designed to make it easy to sell your digital goods and services globally, with support for 44 currencies across 175 storefronts.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              From time to time, we may need to adjust prices or your proceeds due to changes in tax regulations or foreign exchange rates. These adjustments are made using publicly available exchange rate information from financial data providers to help make sure prices for apps and In-App Purchases stay consistent across all storefronts.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              Price updates

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              On June 21, pricing for apps and In-App Purchases¹ will be updated for the Egypt, Ivory Coast, Nepal, Nigeria, Suriname, and Zambia storefronts if you haven’t selected one of these as the base for your app or In‑App Purchase.¹ These updates also consider the following value‑added tax (VAT) changes:

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              • Ivory Coast: VAT introduction of 18%
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              • Nepal: VAT introduction of 13% and digital services tax of 2%
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              • Suriname: VAT introduction of 10%
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              • Zambia: VAT introduction of 16%

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              Prices won’t change on the Egypt, Ivory Coast, Nepal, Nigeria, Suriname, or Zambia storefront if you’ve selected that storefront as the base for your app or In-App Purchase.¹ Prices on other storefronts will be updated to maintain equalization with your chosen base price.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              Prices won’t change in any region if your In‑App Purchase is an auto‑renewable subscription and won’t change on the storefronts where you manually manage prices instead of using the automated equalized prices.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              The Pricing and Availability section of Apps has been updated in App Store Connect to display these upcoming price changes. As always, you can change the prices of your apps, In‑App Purchases, and auto‑renewable subscriptions at any time.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              Learn more about managing your prices

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              View or edit upcoming price changes

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              Edit your app’s base country or region

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              Pricing and availability start times by region

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              Set a price for an In-App Purchase

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              Tax updates

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              Your proceeds for sales of apps and In-App Purchases will change to reflect the new tax rates and updated prices. Exhibit B of the Paid Applications Agreement has been updated to indicate that Apple collects and remits applicable taxes in Ivory Coast, Nepal, Suriname, and Zambia.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              As of today, June 6, your proceeds from the sale of eligible apps and In‑App Purchases have been modified in the following countries to reflect introductions of or changes in tax rates.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              • France: Digital services tax no longer applicable
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              • Ivory Coast: VAT introduction of 18%
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              • Malaysia: Sales and Service Tax (SST) increased to 8% from 6%
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              • Nepal: VAT introduction of 13% and digital services tax introduction of 2%
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              • Norway: VAT increased to 20% from 0% for certain Norwegian news publications
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              • Suriname: VAT introduction of 10%
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              • Uganda: Digital services tax introduction of 5%
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              • Zambia: VAT introduction of 16%
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              Learn more about your proceeds

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              View payments and proceeds

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              Download financial reports

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              Tax categories

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              The Fitness and Health category has a new attribute: “Content is primarily accessed through streaming”. If this is relevant to your apps or In-App Purchases that offer fitness video streaming, review and update your selections in the Pricing and Availability section of Apps in App Store Connect.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              Learn about setting tax categories

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              1: Excludes auto-renewable subscriptions.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              Introducing the 2024 Apple Design Award winners

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                Every year, the Apple Design Awards recognize innovation, ingenuity, and technical achievement in app and game design.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                The incredible developers behind this year’s finalists have shown what can be possible on Apple platforms — and helped lay the foundation for what’s to come.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                We’re thrilled to present the winners of the 2024 Apple Design Awards.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                Meet this year’s winners

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                Action packed.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  One week to go. Don’t miss the exciting reveal of the latest Apple software and technologies.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  Keynote kicks off at 10 a.m. PT on June 10.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  Add to calendar

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  Join us for the Platforms State of the Union at 1 p.m. PT on June 10.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  Add to calendar

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  Learn more

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  Introducing the 2024 Apple Design Award finalists

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    Every year, the Apple Design Awards recognize innovation, ingenuity, and technical achievement in app and game design.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    But they’ve also become something more: A moment to step back and celebrate the Apple developer community in all its many forms.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    Meet this year’s finalists

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    Coming in swiftly.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      Join the worldwide developer community for an incredible week of technology and creativity — all online and free. WWDC24 takes place from June 10-14.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      Get ready

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      Check out the new Apple Developer Forums

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        The Apple Developer Forums have been redesigned for WWDC24 to help developers connect with Apple experts, engineers, and each other to find answers and get advice.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        Apple Developer Relations and Apple engineering are joining forces to field your questions and work to solve your technical issues. You’ll have access to an expanded knowledge base and enjoy quick response times — so you can get back to creating and enhancing your app or game. Plus, Apple Developer Program members now have priority access to expert advice on the forums.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        Check out the new forums

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        Hello Developer: May 2024

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          It won’t be long now! WWDC24 takes place online from June 10 through 14, and we’re here to help you get ready for the biggest developer event of the year. In this edition:

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          • Explore Pathways, a brand-new way to learn about developing for Apple platforms.
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          • Meet three Distinguished Winners of this year’s Swift Student Challenge.
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          • Get great tips from the SharePlay team.
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          • Browse new developer activities about accessibility, machine learning, and more.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          WWDC24

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          Introducing Pathways

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          If you’re new to developing for Apple platforms, we’ve got an exciting announcement. Pathways are simple and easy-to-navigate collections of the videos, documentation, and resources you’ll need to start building great apps and games. Because Pathways are self-directed and can be followed at your own pace, they’re the perfect place to begin your journey.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          Explore Pathways for Swift, SwiftUI, design, games, visionOS, App Store distribution, and getting started as an Apple developer.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          Dive into Pathways >

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          Meet three Distinguished Winners of the Swift Student Challenge

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          Elena Galluzzo, Dezmond Blair, and Jawaher Shaman all drew inspiration from their families to create their winning app playgrounds. Now, they share the hope that their apps can make an impact on others as well.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          Meet Elena, Dezmond, and Jawaher >

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          MEET WITH APPLE EXPERTS

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          Check out the latest worldwide developer activities
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          • Meet with App Review online to discuss the App Review Guidelines and explore best practices for a smooth review process. Sign up for May 14.
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          • Join us in Bengaluru for a special in-person activity to commemorate Global Accessibility Awareness Day. Sign up for May 15.
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          • Learn how Apple machine learning frameworks can help you create more intelligent apps and games in an online activity. Sign up for May 19.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          Browse the full schedule of activities >

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          NEWS

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          Explore Apple Pencil Pro

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          Bring even richer and more immersive interactions to your iPad app with new features, like squeeze gestures, haptic feedback, and barrel-roll angle tracking.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          BEHIND THE DESIGN

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          The rise of Tide Guide

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          Here’s the swell story of how fishing with his grandfather got Tucker MacDonald hooked into creating his tide-predicting app.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          ‘I taught myself’: Tucker MacDonald and the rise of Tide Guide View now

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          GROW YOUR BUSINESS

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          Explore simple, safe transactions with In-App Purchase

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          Take advantage of powerful global pricing tools, promotional features, analytics only available from Apple, built-in customer support, and fraud detection.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          Learn more >

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          Q&A

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          Get shared insights from the SharePlay team

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          Learn about shared experiences, spatial Personas, that magic “shockwave” effect, and more.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          Q&A with the SharePlay team View now

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          DOCUMENTATION

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          Browse new and updated docs Subscribe to Hello Developer

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          Want to get Hello Developer in your inbox? Make sure you’ve opted in to receive emails about developer news and events by updating your email preferences in your developer account.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          Share your thoughts

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          We’d love to hear from you. If you have suggestions for our activities or stories, please let us know.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          Q&amp;A with the SharePlay team

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            SharePlay is all about creating meaningful shared experiences in your app. By taking advantage of SharePlay, your app can provide a real-time connection that synchronizes everything from media playback to 3D models to collaborative tools across iPhone, iPad, Mac, Apple TV, and Apple Vision Pro. We caught up with the SharePlay team to ask about creating great SharePlay experiences, spatial Personas, that magic “shockwave” effect, and more.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            How does a person start a SharePlay experience?

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            Anyone can begin a group activity by starting a FaceTime call and then launching a SharePlay-supported app. When they do, a notification about the group activity will appear on all participants’ screens. From there, participants can join — and come and go — as they like. You can also start a group activity from your app, from the share sheet, or by adding a SharePlay button to your app.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            Learn more >

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            How can I use SharePlay to keep media playback in sync?

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            SharePlay supports coordinated media playback using AVKit. You can use the system coordinator to synchronize your own player across multiple participants. If you have an ad-supported app, you can synchronize both playback and ad breaks. SharePlay also provides the GroupSessionMessenger API, which lets participants communicate in near-real time.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            What’s the difference between SharePlay and Shared with You? Can they work together?

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            SharePlay allows people to share rich experiences with each other. Shared with You helps make app content that people are sharing in Messages available to your app. For example, if a group chat is discussing a funny meme video from your app, adopting Shared with You would allow your app to highlight that content in the app. And if your app supports SharePlay, you can surface that relevant content as an option for watching together.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            Separately, Shared with You offers ways to initiate collaboration on shared, persisted content (such as documents) over Messages and FaceTime. You can choose to support SharePlay on that collaborative content, but if you do, consider the ephemerality of a SharePlay experience compared to the persistence of collaboration. For example, if your document is a presentation, you may wish to leverage Shared with You to get editors into the space while using SharePlay to launch an interactive presentation mode that just isn’t possible with screen sharing alone.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            What’s the easiest way for people to share content?

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            When your app lets your system know that your current view has shareable content on screen, people who bring their devices together can seamlessly share that content — much like NameDrop, which presents a brief “shockwave” animation when they do. This method supports the discrete actions of sharing documents, initiating SharePlay, and starting a collaboration. This can also connect your content to the system share sheet and help you expose shareable content to the Share menu in visionOS.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            Learn more >

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            Can someone on iPhone join a SharePlay session with someone on Apple Vision Pro?

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            Yes! SharePlay is supported across iOS, iPadOS, macOS, tvOS, and visionOS. That means people can watch a show together on Apple TV+ and keep their playback synchronized across all platforms. To support a similar playback situation in your app, watch Coordinate media playback in Safari with Group Activities. If you’re looking to maintain your app’s visual consistency across platforms, check out the Group Session Messenger and DrawTogether sample project. Remember: SharePlay keeps things synchronized, but your UI is up to you.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            How do I get started adopting spatial Personas with SharePlay in visionOS?

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            When you add Group Activities to your app, people can share in that activity over FaceTime while appearing windowed — essentially the same SharePlay experience they’d see on other platforms. In visionOS, you have the ability to create a shared spatial experience using spatial Personas in which participants are placed according to a template. For example:

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            Using spatial Personas, the environment is kept consistent and participants can see each others’ facial expressions in real time.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            Learn more >

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            How do I maintain visual and spatial consistency with all participants in visionOS?

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            FaceTime in visionOS provides a shared spatial context by placing spatial Personas in a consistent way around your app. This is what we refer to as “visual consistency.” You can use SharePlay to maintain the same content in your app for all participants.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            Learn more >

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            Can both a window and a volume be shared at the same time in a SharePlay session?

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            No. Only one window or volume can be associated with a SharePlay session, but you can help the system choose the proper window or volume.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            Learn more >

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            How many people can participate in a group activity?

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            SharePlay supports 33 total participants, including yourself. Group activities on visionOS involving spatial Personas support five participants at a time.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            Do iOS and iPadOS apps that are compatible with visionOS also support SharePlay in visionOS?

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            Yes. During a FaceTime call, your app will appear in a window, and participants in the FaceTime call will appear next to it.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            Learn more about SharePlay Design spatial SharePlay experiences Watch now Build spatial SharePlay experiences Watch now Share files with SharePlay Watch now Add SharePlay to your app Watch now

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            ‘I taught myself’: Tucker MacDonald and the rise of Tide Guide

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              Lots of apps have great origin stories, but the tale of Tucker MacDonald and Tide Guide seems tailor-made for the Hollywood treatment. It begins in the dawn hours on Cape Cod, where a school-age MacDonald first learned to fish with his grandfather.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              “Every day, he’d look in the paper for the tide tables,” says MacDonald. “Then he’d call me up and say, ‘Alright Tucker, we’ve got a good tide and good weather. Let’s be at the dock by 5:30 a.m.’”

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              Rhapsody in blue: In this iPad image, Tide Guide delivers South Carolina weather data in a gorgeous design and color scheme.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              That was MacDonald’s first introduction to tides — and the spark behind Tide Guide, which delivers comprehensive forecasts through top-notch data visualizations, an impressive array of widgets, an expanded iPad layout, and Live Activities that look especially great in, appropriately enough, the Dynamic Island. The SwiftUI-built app also offers beautiful Apple Watch complications and a UI that can be easily customized, depending how deep you want to dive into its data. It’s a remarkable blend of original design and framework standards, perfect for plotting optimal times for a boat launch, research project, or picnic on the beach.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              Impressively, Tide Guide was named a 2023 Apple Design Award finalist — no mean feat for a solo developer who had zero previous app-building experience and started his career as a freelance filmmaker.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              “I wanted to be a Hollywood director since I was in the fifth grade,” says MacDonald. Early in his filmmaking career, MacDonald found himself in need of a tool that could help him pre-visualize different camera and lens combinations — “like a director’s viewfinder app,” he says. And while he caught a few decent options on the market, MacDonald wanted an app with iOS design language that felt more at home on his iPhone. “So I dove in, watched videos, and taught myself how to make it,” he says.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              My primary use cases were going fishing, heading to the beach, or trying to catch a sunset.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              Tucker MacDonald, Tide Guide

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              Before too long, MacDonald drifted away from filmmaking and into development, taking a job as a UI designer for a social app. “The app ended up failing, but the job taught me how a designer works with an engineer,” he says. “I also learned a lot about design best practices, because I had been creating apps that used crazy elements, non-standard navigation, stuff like that.”

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              Tucker MacDonald grew up fishing with his grandfather in the waters off Cape Cod.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              Armed with growing design knowledge, he started thinking about those mornings with his grandfather, and how he might create something that could speed up the crucial process of finding optimal fishing conditions. And it didn’t need to be rocket science. “My primary use cases were going fishing, heading to the beach, or trying to catch a sunset,” he says. “I just needed to show current conditions.”

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              I’d say my designs were way prettier than the code I wrote.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              Tucker MacDonald, Tide Guide

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              In the following years, Tide Guide grew in parallel with MacDonald’s self-taught skill set. “There was a lot of trial and error, and I’d say my designs were way prettier than the code I wrote,” he laughs. “But I learned both coding and design by reading documentation and asking questions in the developer community.”

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              Today’s Tide Guide is quite the upgrade from that initial version. MacDonald continues to target anyone heading to the ocean but includes powerful metrics — like an hour-by-hour 10-day forecast, water temperatures, and swell height — that advanced users can seek out as needed. The app’s palette is even designed to match the color of the sky throughout the day. “The more time you spend with it, the more you can dig into different layers,” he says.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              All the information you need for a day on the water, in one place.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              People around the world have dug into those layers, including an Alaskan tour company operator who can only land in a remote area when the tide is right, and a nonprofit national rescue service in Scotland, whose members weighed in with a Siri shortcut-related workflow request that MacDonald promptly included. And as Tide Guide gets bigger, MacDonald’s knowledge of developing — and oceanography — continues to swell. “I’m just happy that my passion for crafting an incredible experience comes through,” he says, “because I really do have so much fun making it.”

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              Learn more about Tide Guide

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              Download Tide Guide from the App Store

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              Behind the Design is a series that explores design practices and philosophies from finalists and winners of the Apple Design Awards. In each story, we go behind the screens with the developers and designers of these award-winning apps and games to discover how they brought their remarkable creations to life.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              What’s new for apps distributed in the European Union

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                Core Technology Fee (CTF)

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                The CTF is an element of the alternative business terms in the EU that reflects the value Apple provides developers through tools, technologies, and services that enable them to build and share innovative apps. We believe anyone with a good idea and the ingenuity to bring it to life should have the opportunity to offer their app to the world. Only developers who reach significant scale (more than one million first annual installs per year in the EU) pay the CTF. Nonprofit organizations, government entities, and educational institutions approved for a fee waiver don’t pay the CTF. Today, we’re introducing two additional conditions in which the CTF is not required:

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                • First, no CTF is required if a developer has no revenue whatsoever. This includes creating a free app without monetization that is not related to revenue of any kind (physical, digital, advertising, or otherwise). This condition is intended to give students, hobbyists, and other non-commercial developers an opportunity to create a popular app without paying the CTF.
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                • Second, small developers (less than €10 million in global annual business revenue*) that adopt the alternative business terms receive a 3-year free on-ramp to the CTF to help them create innovative apps and rapidly grow their business. Within this 3-year period, if a small developer that hasn’t previously exceeded one million first annual installs crosses the threshold for the first time, they won’t pay the CTF, even if they continue to exceed one million first annual installs during that time. If a small developer grows to earn global revenue between €10 million and €50 million within the 3-year on-ramp period, they’ll start to pay the CTF after one million first annual installs up to a cap of €1 million per year.
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                iPadOS

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                This week, the European Commission designated iPadOS a gatekeeper platform under the Digital Markets Act. Apple will bring our recent iOS changes for apps in the European Union (EU) to iPadOS later this fall, as required. Developers can choose to adopt the Alternative Terms Addendum for Apps in the EU that will include these additional capabilities and options on iPadOS, or stay on Apple’s existing terms.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                Once these changes are publicly available to users in the EU, the CTF will also apply to iPadOS apps downloaded through the App Store, Web Distribution, and/or alternative marketplaces. Users who install the same app on both iOS and iPadOS within a 12-month period will only generate one first annual install for that app. To help developers estimate any potential impact on their app businesses under the Alternative Terms Addendum for Apps in the EU, we’ve updated the App Install reports in App Store Connect that can be used with our fee calculator.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                For more details, visit Understanding the Core Technology Fee for iOS apps in the European Union. If you’ve already entered into the Alternative Terms Addendum for Apps in the EU, be sure to sign the updated terms.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                Global business revenue takes into account revenue across all commercial activity, including from associated corporate entities. For additional details, read the Alternative Terms Addendum for Apps in the EU.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                Reminder: Privacy requirement for app submissions starts May 1

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  The App Store was created to be a safe place for users to discover and get millions of apps all around the world. Over the years, we‘ve built many critical privacy and security features that help protect users and give them transparency and control — from Privacy Nutrition Labels to app tracking transparency, and so many more.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  An essential requirement of maintaining user trust is that developers are responsible for all of the code in their apps, including code frameworks and libraries from other sources. That‘s why we’ve created privacy manifests and signature requirements for the most popular third-party SDKs, as well as required reasons for covered APIs.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  Starting May 1, 2024, new or updated apps that have a newly added third-party SDK that‘s on the list of commonly used third-party SDKs will need all of the following to be submitted in App Store Connect:

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  1. Required reasons for each listed API
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  2. Privacy manifests
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  3. Valid signatures when the SDK is added as a binary dependency

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  Apps won’t be accepted if they fail to meet the manifest and signature requirements. Apps also won’t be accepted if all of the following apply:

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  1. They’re missing a reason for a listed API
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  2. The code is part of a dynamic framework embedded via the Embed Frameworks build phase
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  3. The framework is a newly added third-party SDK that’s on the list of commonly used third-party SDKs

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  In the future, these required reason requirements will expand to include the entire app binary. If you’re not using an API for an approved reason, please find an alternative. These changes are designed to help you better understand how third-party SDKs use data, secure software dependencies, and provide additional privacy protection for users.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  This is a step forward for all apps and we encourage all SDKs to adopt this functionality to better support the apps that depend on them.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  Q&amp;A: Promoting your app or game with Apple Search Ads

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    Apple Search Ads helps you drive discovery of your app or game on the App Store. We caught up with the Apple Search Ads team to learn more about successfully using the service, including signing up for the free online Apple Search Ads Certification course.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    How might my app or game benefit from promotion on the App Store?

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    With Apple Search Ads, developers are seeing an increase in downloads, retention, return on ad spend, and more. Find out how the developers behind The Chefz, Tiket, and Petit BamBou have put the service into practice.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    Where will my ad appear?

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    You can reach people in the following places:

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    How can I learn best practices for creating and managing campaigns?

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    Online Apple Search Ads Certification training teaches proven best practices for driving stronger campaign performance. Certification training is designed for all skill levels, from marketing pros to those just starting out. To become certified, complete all of the Certification lessons (each takes between 10 and 20 minutes), then test your skills with a free exam. Once you’re certified, you can share your certificate with your professional network on platforms like LinkedIn.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    Sign up here with your Apple ID.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    Will my certification expire?

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    Although your Apple Search Ads certification never expires, training is regularly updated. You can choose to be notified about these updates through email or web push notifications.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    Can I highlight specific content or features in my ads?

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    You can use the custom product pages you create in App Store Connect to tailor your ads for a specific audience, feature launch, seasonal promotion, and more. For instance, you can create an ad for the Today tab that leads people to a specific custom product page or create ad variations for different search queries. Certification includes a lesson on how to do so.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    Can I advertise my app before launch?

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    You can use Apple Search Ads to create ads for apps you’ve made available for pre-order. People can order your app before it’s released, and it’ll automatically download onto their devices on release day.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    Apple Search Ads now available in Brazil and more Latin American markets

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      Drive discovery and downloads on the App Store with Apple Search Ads in 70 countries and regions, now including Brazil, Bolivia, Costa Rica, the Dominican Republic, El Salvador, Guatemala, Honduras, Panama, and Paraguay.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      Visit the Apple Search Ads site and Q&A.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      And explore best practices to improve your campaign performance with the free Apple Search Ads Certification course.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      Let loose.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        Watch the May 7 event at apple.com, on Apple TV, or on YouTube Live.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        Check out our newest developer activities

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          Join us around the world to learn about growing your business, elevating your app design, and preparing for the App Review process. Here’s a sample of our new activities — and you can always browse the full schedule to find more.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          Browse the full schedule

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          Web Distribution now available in iOS 17.5 beta 2 and App Store Connect

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            Web Distribution lets authorized developers distribute their iOS apps to users in the European Union (EU) directly from a website owned by the developer. Apple will provide developers access to APIs that facilitate the distribution of their apps from the web, integrate with system functionality, and back up and restore users’ apps, once they meet certain requirements designed to help protect users and platform integrity. For details, visit Getting started with Web Distribution in the EU.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            Get ready with the latest beta releases

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              The beta versions of iOS 17.5, iPadOS 17.5, macOS 14.5, tvOS 17.5, visionOS 1.2, and watchOS 10.5 are now available. Get your apps ready by confirming they work as expected on these releases. And to take advantage of the advancements in the latest SDKs, make sure to build and test with Xcode 15.3.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              View downloads and release notes

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              Learn about testing a beta OS

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              Learn about sending feedback

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              Updated App Review Guidelines now available

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                The App Review Guidelines have been revised to support updated policies, upcoming features, and to provide clarification. The following guidelines have been updated:

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                • 3.1.1(a): Updated to include Music Streaming Services Entitlements.
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                • 4.7: Added games from retro game console emulator apps to the list of permitted software, and clarifies that mini apps and mini games must be HTML5.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                View guidelines

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                Hello Developer: April 2024

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  Welcome to Hello Developer — and the kickoff to WWDC season. In this edition:

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  • Discover what’s ahead at WWDC24 — and check out the new Apple Developer YouTube channel.
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  • Learn how the all-new Develop in Swift Tutorials can help jump-start a career in app development.
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  • Find out how Zach Gage and Jack Schlesinger rebooted the crossword puzzle with Knotwords.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  WWDC24

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  The countdown is on

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  WWDC season is officially here.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  This year’s Worldwide Developers Conference takes place online from June 10 through 14, offering you the chance to explore the new tools, frameworks, and technologies that’ll help you create your best apps and games yet.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  All week long, you can learn and refine new skills through video sessions, meet with Apple experts to advance your projects and ideas, and join the developer community for fun activities. It’s an innovative week of technology and creativity — all online at no cost.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  And for the first time, WWDC video sessions will be available on YouTube, in addition to the Apple Developer app and website. Visit the new Apple Developer channel to subscribe and catch up on select sessions.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  TUTORIALS

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  Check out the new Develop in Swift Tutorials

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  Know a student or aspiring developer looking to start their coding journey? Visit the all-new Develop in Swift Tutorials, designed to introduce Swift, SwiftUI, and spatial computing through the experience of building a project in Xcode.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  BEHIND THE DESIGN

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  Gage and Schlesinger at the crossroads

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  Learn how acclaimed game designers Zach Gage and Jack Schlesinger reimagined the crossword with Knotwords.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  Knotwords: Gage and Schlesinger at the crossroads View now

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  MEET WITH APPLE EXPERTS

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  Browse new developer activities

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  Check out this month’s sessions, labs, and consultations, held online and in person around the world.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  NEWS AND DOCUMENTATION

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  Explore and create with new and updated docs

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  View the complete list of new resources.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  Subscribe to Hello Developer

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  Want to get Hello Developer in your inbox? Make sure you’ve opted in to receive emails about developer news and events by updating your email preferences in your developer account.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  Share your thoughts

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  We’d love to hear from you. If you have suggestions for our activities or stories, please let us know.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  Knotwords: Gage and Schlesinger at the crossroads

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    Knotwords is a clever twist on crossword puzzles — so much so that one would expect creators Zach Gage and Jack Schlesinger to be longtime crossword masters who set out to build themselves a new challenge.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    One would be totally wrong.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    “Crosswords never hit with me,” says Gage, with a laugh. “I dragged myself kicking and screaming into this one.”

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    It’s not about ‘What random box of words will you get?’ but, ‘What are the decisions you’ll make as a player?’

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    Jack Schlesinger, Knotwords

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    In fact, Gage and Schlesinger created the Apple Design Award finalist Knotwords — and the Apple Arcade version, Knotwords+ — not to revolutionize the humble crossword but to learn it. “We know people like crosswords,” says Schlesinger, “so we wanted to figure out what we were missing.” And the process didn’t just result in a new game — it led them straight to the secret of word-game design success. “It’s not about ‘What random box of words will you get?’” says Schlesinger, “but, ‘What are the decisions you’ll make as a player?’”

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    Knotwords challenges players to complete a puzzle using only specific letters in specific parts of the board.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    Gage and Schlesinger are longtime design partners; in addition to designing Knotwords and Good Sudoku with Gage, Schlesinger contributed to the 2020 reboot of SpellTower and the Apple Arcade title Card of Darkness. Neither came to game design through traditional avenues: Gage has a background in interactive art, while Schlesinger is the coding mastermind with a history in theater and, of all things, rock operas. (He’s responsible for the note-perfect soundtracks for many of the duo’s games.) And they’re as likely to talk about the philosophy behind a game as the development of it.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    I had been under the mistaken impression that the magic of a simple game was in its simple rule set. The magic actually comes from having an amazing algorithmic puzzle constructor.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    Zach Gage

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    “When you’re playing a crossword, you’re fully focused on the clues. You’re not focused on the grid at all,” explains Gage. “But when you’re building a crossword, you’re always thinking about the grid. I wondered if there was a way to ask players not to solve a crossword but recreate the grid instead,” he says.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    Knotwords lets players use only specific letters in specific sections of the grid — a good idea, but one that initially proved elusive to refine and difficult to scale. “At first, the idea really wasn’t coming together,” says Gage, “so we took a break and built Good Sudoku.” Building their take on sudoku — another game with simple rules and extraordinary complexity — proved critical to restarting Knotwords. “I had been under the mistaken impression that the magic of a simple game was in its simple rule set,” Gage says. “The magic actually comes from having an amazing algorithmic puzzle constructor.”

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    An early — and very analog — prototype of Knotwords.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    Problematically, they didn’t just have one of those just lying around. But they did have Schlesinger. “I said, ‘I will make you a generator for Knotwords in two hours,’” Schlesinger laughs. That was maybe a little ambitious. The first version took eight hours and was, by his own account, not great. However, it proved a valuable learning experience. “We learned that we needed to model a player. What would someone do here? What steps could they take? If they make a mistake, how long would it take them to correct it?” In short, the puzzle generation algorithm needed to take into account not just rules, but also player behavior.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    The work provided the duo an answer for why people liked crosswords. It also did one better by addressing one of Gage’s longstanding game-design philosophies. “To me, the only thing that’s fun in a game is the process of getting better,” says Gage. “In every game I’ve made, the most important questions have been: What’s the journey that people are going through and how can we make that journey fun? And it turns out it's easy to discover that if I've never played a game before.”

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    Learn more about Knotwords

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    Find Knotwords+ on Apple Arcade

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    Behind the Design is a series that explores design practices and philosophies from each of the winners and finalists of the Apple Design Awards. In each story, we go behind the screens with the developers and designers of these award-winning apps and games to discover how they brought their remarkable creations to life.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    WWDC24: June 10-14

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      Join the worldwide developer community online for a week of technology and creativity.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      Be there for the unveiling of the latest Apple platforms, technologies, and tools. Learn how to create and elevate your apps and games. Engage with Apple designers and engineers and connect with the worldwide developer community. All online and at no cost.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      Learn more

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      Provide your trader status in App Store Connect

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        To align with the Digital Services Act (DSA) in the European Union (EU), Account Holders and Admins in the Apple Developer Program can now enter their trader status in App Store Connect.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        Submission requirements

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        You’ll need to let us know whether or not you’re a trader to submit new apps to the App Store. If you’re a trader, you may be asked for documentation that verifies your trader contact information.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        More options for apps distributed in the European Union

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          We’re providing more flexibility for developers who distribute apps in the European Union (EU), including introducing a new way to distribute apps directly from a developer’s website.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          More flexibility

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          Developers who’ve agreed to the Alternative Terms Addendum for Apps in the EU have new options for their apps in the EU:

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          • Alternative app marketplaces. Marketplaces can choose to offer a catalog of apps solely from the developer of the marketplace.
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          • Linking out to purchase. When directing users to complete a transaction for digital goods or services on an external webpage, developers can choose how to design promotions, discounts, and other deals. The Apple-provided design templates, which are optimized for key purchase and promotional use cases, are now optional.
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          Distributing directly from your website

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          Web Distribution, available with a software update later this spring, will let authorized developers distribute their iOS apps to EU users directly from a website owned by the developer. Apple will provide authorized developers access to APIs that facilitate the distribution of their apps from the web, integrate with system functionality, back up and restore users’ apps, and more. For details, visit Getting ready for Web Distribution in the EU.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          Uncovering the hidden joys of Finding Hannah

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            On its surface, Finding Hannah is a bright and playful hidden-object game — but dig a little deeper and you’ll find something much more.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            The Hannah of Finding Hannah is a 38-year-old Berlin resident trying to navigate career, relationships (including with her best friend/ex, Emma), and the nagging feeling that something’s missing in her life. To help find answers, Hannah turns to her nurturing grandmother and free-spirited mother — whose own stories gradually come into focus and shape the game’s message as well.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            “It’s really a story about three women from three generations looking for happiness,” says Franziska Zeiner, cofounder and co-CEO of the Fein Games studio. “For each one, times are changing. But the question is: Are they getting better?”

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            Locate hidden objects in this lively Berlin subway scene to move along the story of Finding Hannah.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            To move the story along, players comb through a series of richly drawn scenes — a packed club, a bustling train, a pleasantly cluttered bookstore. Locating (and merging) hidden items unlocks new chapters, and the more you find, the more the time-hopping story unfolds. The remarkable mix of message and mechanic made the game a 2023 Apple Design Award finalist, as well as a Cultural Impact winner in the 2023 App Store Awards.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            Fein Games is the brainchild of Zeiner and Lea Schönfelder, longtime friends from the same small town in Germany who both pursued careers in game design — despite not being all that into video games growing up. “I mean, at some point I played The Sims as a teenager,” laughs Zeiner, “but games were rare for us. When I eventually went to study game design, I felt like I didn’t really fit in, because my game literacy was pretty limited.”

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            The goal is to create for people who enjoy authentic female experiences in games.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            Lea Schönfelder, cofounder and co-CEO of Fein Games

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            Cofounder and co-CEO Schönfelder also says she felt like an outsider, but soon found game design a surprisingly organic match for her background in illustration and animation. “In my early years, I saw a lot of people doing unconventional things with games and thought, ‘Wow, this is really powerful.’ And I knew I loved telling stories, maybe not in a linear form but a more systematic way.” Those early years included time with studios like Nerial and ustwo Games, where she worked on Monument Valley 2 and Assemble With Care.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            Drawing on their years of experience — and maybe that shared unconventional background — the pair went out on their own to launch Fein Games in 2020. From day one, the studio was driven by more than financial success. “The goal is to create for people who enjoy authentic female experiences in games,” says Schönfelder. “But the product is only one side of the coin — there’s also the process of how you create, and we’ve been able to make inclusive games that maybe bring different perspectives to the world.”

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            Hannah and her free-spirited mother, Sigrid, share an uncomfortable conversation.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            Finding Hannah was driven by those perspectives from day one. The story was always meant to be a time-hopping journey featuring women in Berlin, and though it isn’t autobiographical, bits and pieces do draw from their creators’ lives. “There’s a scene inspired by my grandmother, who was a nurse during the second world war and would tan with her friends on a hospital roof while the planes circled above,” says Schönfelder. The script was written by Berlin-based author Rebecca Harwick, who also served as lead writer on June’s Journey and writer on Switchcraft, The Elder Scrolls Online, and many others.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            In the beginning, I felt like I wasn’t part of the group, and maybe even a little ashamed that I wasn’t as games-literate as my colleagues. But what I thought was a weakness was actually a strength.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            Lea Schönfelder, cofounder and co-CEO of Fein Games

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            To design the art for the different eras, the team tried not to think like gamers. “The idea was to try to reach people who weren’t gamers yet, and we thought we’d most likely be able to do that if we found a style that hadn’t been seen in games before,” says Zeiner. To get there, they hired Elena Resko, a Russian-born artist based in Berlin who’d also never worked in games. “What you see is her style,” says Schönfelder. “She didn’t develop that for the game. I think that’s why it has such a deep level of polish, because Elena has been developing her style for probably a decade now.”

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            And the hidden-object and merge gameplay mechanic itself is an example of sticking with a proven success. “When creating games, you usually want to invent a new mechanic, right?” says Schönfelder. “But Finding Hannah is for a more casual audience. And it’s been proven that the hidden-object mechanic works. So we eventually said, ‘Well, maybe we don’t need to reinvent the wheel here,’” she laughs.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            The scene in which Hannah’s grandmother sits with friends on the roof was inspired by Lea Schönfelder’s grandmother.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            The result is a hidden-object game like none other, part puzzler, part historically flavored narrative, part meditation on the choices faced by women across generations. And it couldn’t have come from a team with any other background. “In the beginning, I felt like I wasn’t part of the group, and maybe even a little ashamed that I wasn’t as games-literate as my colleagues,” says Schönfelder. “But what I thought was a weakness was actually a strength. Players don’t always play your game like you intended. And I felt a very strong, very sympathetic connection to people, and wanted to make the experience as smooth and accessible as possible. And I think that shows.”

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            Learn more about Finding Hannah

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            Download Finding Hannah from the App Store

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            Behind the Design is a series that explores design practices and philosophies from finalists and winners of the Apple Design Awards. In each story, we go behind the screens with the developers and designers of these award-winning apps and games to discover how they brought their remarkable creations to life.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            Q&amp;A with the Mac notary service team

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              Security is at the core of every Apple platform. The Mac notary service team is part of Apple Security Engineering and Architecture, and in this Q&A, they share their tips on app distribution and account security to help Mac developers have a positive experience — and protect their users.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              When should I submit my new app for notarization?

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              Apps should be mostly complete at the time of notarization. There’s no need to notarize an app that isn’t functional yet.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              How often should I submit my app for notarization?

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              You should submit all versions you might want to distribute, including beta versions. That’s because we build a profile of your unique software to help distinguish your apps from other developers’ apps, as well as malware. As we release new signatures to block malware, this profile helps ensure that the software you’ve notarized is unaffected.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              What happens if my app is selected for additional analysis?

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              Some uploads to the notary service require additional evaluation. If your app falls into this category, rest assured that we’ve received your file and will complete the analysis, though it may take longer than usual. In addition, if you’ve made changes to your app while a prior upload has been delayed, it’s fine to upload a new build.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              What should I do if my app is rejected?

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              Keep in mind that empty apps or apps that might damage someone’s computer (by changing important system settings without the owner’s knowledge, for instance) may be rejected, even if they’re not malicious. If your app is rejected, first confirm that your app doesn’t contain malware. Then determine whether it should be distributed privately instead, such as within your enterprise via MDM.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              What should I do if my business changes?

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              Keep your developer account details — including your business name, contact info, address, and agreements — up to date. Drastic shifts in account activity or software you notarize can be signs that your account or certificate has been compromised. If we notice this type of activity, we may suspend your account while we investigate further.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              I’m a contractor. What are some ways to make sure I’m developing responsibly?

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              Be cautious if anyone asks you to:

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              • Sign, notarize, or distribute binaries that you didn’t develop.
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              • Develop software that appears to be a clone of existing software.
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              • Develop what looks like an internal enterprise application when your customer isn’t an employee of that company.
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              • Develop software in a high-risk category, like VPNs, system utilities, finance, or surveillance apps. These categories of software have privileged access to private data, increasing the risk to users.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              Remember: It’s your responsibility to know your customer and the functionality of all software you build and/or sign.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              What can I do to maintain control of my developer account?

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              Since malware developers may try to gain access to legitimate accounts to hide their activity, be sure you have two-factor authentication enabled. Bad actors may also pose as consultants or employees and ask you to add them to your developer team. Luckily, there’s an easy solve: Don’t share access to your accounts.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              Should I remove access for developers who are no longer on my team?

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              Yes. And we can revoke Developer ID certificates for you if you suspect they may have been compromised.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              Learn more about notarization

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              Notarizing macOS software before distribution

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              Developer agreement for notarizing macOS applications

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              Two-factor authentication for developer accounts

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              Hello Developer: March 2024

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                Welcome to Hello Developer. In this edition:

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                • Find out what you can do at the Apple Developer Centers in Bengaluru, Cupertino, Shanghai, and Singapore.
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                • Learn how the team behind Finding Hannah created a hidden-object game with a meaningful message.
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                • Get security tips from the Mac notary service team.
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                • Catch up on the latest news and documentation.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                FEATURED

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                Step inside the Apple Developer Centers

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                The new Apple Developer Centers are open around the world — and we can’t wait for you to come by. With locations in Bengaluru, Cupertino, Shanghai, and now Singapore, Apple Developer Centers are the home bases for in-person sessions, labs, workshops, and consultations around the world.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                Whether you’re looking to enhance your existing app or game, refine your design, or launch a new project, there’s something exciting for you at the Apple Developer Centers. Browse activities in Bengaluru, Cupertino, Shanghai, and Singapore.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                BEHIND THE DESIGN

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                Uncover the hidden joys of Finding Hannah

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                On its surface, Finding Hannah is a bright and playful hidden-object game — but dig a little deeper and you’ll find something more. “It’s really a story about three women from three generations looking for happiness,” says Franziska Zeiner, cofounder and co-CEO of the Fein Games studio. “For each one, times are changing. But the question is: Are they getting better?” Find out how Zeiner and her Berlin-based team created this compelling Apple Design Award finalist.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                Uncovering the hidden joys of Finding Hannah View now

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                Q&A

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                Get answers from the Mac notary service team

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                Security is at the core of every Apple platform. The Mac notary service team is part of Apple Security Engineering and Architecture, and in this Q&A, they share their tips on app distribution and account security to help Mac developers have a positive experience — and protect their users.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                Q&A with the Mac notary service team View now

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                VIDEOS

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                Improve your subscriber retention with App Store features

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                In this new video, App Store experts share their tips for minimizing churn and winning back subscribers.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                Improve your subscriber retention with App Store features Watch now

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                GROW YOUR BUSINESS

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                Make the most of custom product pages

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                Learn how you can highlight different app capabilities and content through additional (and fully localizable) versions of your product page. With custom product pages, you can create up to 35 additional versions — and view their performance data in App Store Connect.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                Plus, thanks to seamless integration with Apple Search Ads, you can use custom product pages to easily create tailored ad variations on the App Store. Read how apps like HelloFresh, Pillow, and Facetune used the feature to gain performance improvements, like higher tap-through and conversion rates.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                DOCUMENTATION

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                Find the details you need in new and updated docs

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                View the full list of new resources

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                NEWS

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                Catch up on the latest updates Subscribe to Hello Developer

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                Want to get Hello Developer in your inbox? Make sure you’ve opted in to receive emails about developer news and events by updating your email preferences in your developer account.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                Share your thoughts

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                We’d love to hear from you. If you have suggestions for our activities or stories, please let us know.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                New App Store and iOS data analytics now available

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  We’re expanding the analytics available for your apps to help you get even more insight into your business and apps’ performance.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  Over 50 new reports are now available through the App Store Connect API to help you analyze your apps’ App Store and iOS performance. These reports include hundreds of new metrics that can enable you to evaluate your performance and find opportunities for improvement. Reports are organized into the following categories:

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  • App Store Engagement — the number of users on the App Store interacting with a developer’s app or sharing it with others
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  • App Store Commerce — downloads, sales, pre-orders, and transactions made with the secure App Store In-App Purchase system
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  • App Usage — active devices, installs, app deletions, and more
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  • Frameworks Usage — an app’s interaction with OS capabilities, such as PhotoPicker and Widgets
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  • Performance — how your apps perform and how users interact with specific features

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  Additionally, new reports are also available through the CloudKit console with data about Apple Push Notifications and File Provider.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  • Apple Push Notifications — notification states as they pass through the Apple Push Notification service (APNs)
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  • File Provider — usage, consistency, and error data

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  Updates to app distribution in the European Union

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    Over the past several weeks, we’ve communicated with thousands of developers to discuss DMA-related changes to iOS, Safari, and the App Store impacting apps in the European Union. As a result of the valuable feedback received, we’ve revised the Alternative Terms Addendum for Apps in the EU to update the following policies and provide developers more flexibility:

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    • Decisioning by membership: To make it easier for more developers to sign up for the new terms, we’ve removed the corporate entity requirement that the Addendum must be signed by each membership that controls, is controlled by, or is under control with another membership. This means an entity can now choose to sign up for the new terms at the developer account level.
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    • Switching back: To help reduce the risk of unexpected business changes under the new terms, such as reaching massive scale more quickly than anticipated, or if you simply change your mind, we’ve created a one-time option to terminate the Addendum under certain circumstances and switch back to Apple’s standard business terms for your EU apps. For details, view the Addendum.
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    • Alternative app marketplace requirements: To make it easier for developers who want to create alternative app marketplaces, we’ve added a new eligibility criteria that lets developers qualify without a stand-by letter of credit. For details, view the marketplace support page.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    If you’ve already entered into the Addendum, you can sign the updated version here.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    The latest OS Release Candidates are now available

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      You can now submit your apps and games built with Xcode 15.3 and all the latest SDKs for iOS 17.4, iPadOS 17.4, macOS 14.4, tvOS 17.4, visionOS 1.1, and watchOS 10.4.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      Developers who have agreed to the Alternative Terms Addendum for Apps in the EU can now submit apps offering alternative payment options in the EU. They can also now measure the number of first annual installs their apps have accumulated.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      If you’d like to discuss changes to iOS, Safari, and the App Store impacting apps in the EU to comply with the Digital Markets Act, request a 30-minute online consultation with an Apple team member.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      Updated App Review Guidelines now available

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        The App Store Review Guidelines have been revised to support updated policies, upcoming features, and to provide clarification.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        • The title of the document has been changed to App Review Guidelines.
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        • The Introduction section explains that in the European Union, developers can also distribute notarized iOS apps from alternative app marketplaces. This section provides links to further information about alternative app marketplaces and Notarization for iOS apps.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        The following guidelines have been updated:

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        • 2.3.1: Added that a violation of this rule is grounds for an app being blocked from installing via alternative distribution.
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        • 2.3.10: Added that developers cannot include names, icons, or imagery of other mobile platforms or alternative app marketplaces in their apps or metadata, unless there is specific, approved interactive functionality.
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        • 3.1.3(b): Added a link to 3.1.1 to make clear that 3.1.1(a) applies, and multiplatform services apps can use the 3.1.1(a) entitlement.
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        • 4.8 Login Services: Updated to make clear that the login service cannot collect interactions with your app for advertising purposes without consent. It also adds that another login service is not required if your app is an alternative app marketplace, or an app distributed from an alternative app marketplace, that uses a marketplace-specific login for account, download, and commerce features.
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        • 5.1.1(viii): Added that apps that compile personal information from any source that is not directly from the user or without the user’s explicit consent, even public databases, are not permitted on alternative app marketplaces.
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        • 5.4 and 5.5: Updated to state that apps that do not comply with these guidelines will be blocked from installing via alternative distribution.
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        • Bug Fix Submissions: Added that bug fixes will not be delayed for apps that are already on alternative app marketplaces, except for those related to legal or safety issues.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        View the App Review Guidelines

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        Translations of the guidelines will be available on the Apple Developer website within one month.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        Privacy updates for App Store submissions

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          Developers are responsible for all code included in their apps. At WWDC23, we introduced new privacy manifests and signatures for commonly used third-party SDKs and announced that developers will need to declare approved reasons for using a set of APIs in their app’s privacy manifest. These changes help developers better understand how third-party SDKs use data, secure software dependencies, and provide additional privacy protection for users.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          Starting March 13: If you upload a new or updated app to App Store Connect that uses an API requiring approved reasons, we’ll send you an email letting you know if you’re missing reasons in your app’s privacy manifest. This is in addition to the existing notification in App Store Connect.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          Starting May 1: You’ll need to include approved reasons for the listed APIs used by your app’s code to upload a new or updated app to App Store Connect. If you’re not using an API for an allowed reason, please find an alternative. And if you add a new third-party SDK that’s on the list of commonly used third-party SDKs, these API, privacy manifest, and signature requirements will apply to that SDK. Make sure to use a version of the SDK that includes its privacy manifest and note that signatures are also required when the SDK is added as a binary dependency.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          This functionality is a step forward for all apps and we encourage all SDKs to adopt it to better support the apps that depend on them.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          App submissions now open for the latest OS releases

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            Submit in App Store Connect

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            iOS 17.4, iPadOS 17.4, macOS 14.4, tvOS 17.4, visionOS 1.1, and watchOS 10.4 will soon be available to customers worldwide. Build your apps and games using the Xcode 15.3 Release Candidate and latest SDKs, then test them using TestFlight. You can submit your iPhone and iPad apps today.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            Apps in the European Union

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            Developers who’ve agreed to the Alternative Terms Addendum for Apps in the EU can set up marketplace distribution in the EU. Eligible developers can also submit marketplace apps and offer apps with alternative browser engines.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            Once these platform versions are publicly available:

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            • First annual installs for the Core Technology Fee begin accruing and the new commission rates take effect for these developers.
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            • Apps offering alternative payment options in the EU will be accepted in App Store Connect. In the meantime, you can test in the sandbox environment.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            If you’d like to discuss changes to iOS, Safari, and the App Store impacting apps in the EU to comply with the Digital Markets Act, request a 30-minute online consultation to meet with an Apple team member. In addition, if you’re interested in getting started with operating an alternative app marketplace on iOS in the EU, you can request to attend an in-person lab in Cork, Ireland.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            Sign in to App Store Connect

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            Developer activities you’ll love

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              Apple developer activities are in full swing. Here’s a look at what’s happening:

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              And we’ll have lots more activities in store — online, in person, and in multiple languages — all year long.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              Browse the schedule

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              Q&amp;A with the Apple UX writing team

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                Writing is fundamental — especially in your apps and games, where the right words can have a profound impact on your experience. During WWDC23, the Apple UX writing team hosted a wide-ranging Q&A that covered everything from technical concepts to inspiring content to whether apps should have “character.” Here are some highlights from that conversation and resources to help you further explore writing for user interfaces.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                Writing for interfaces Watch now My app has a lot of text. What’s the best way to make copy easier to read?

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                Ask yourself: What am I trying to accomplish with my writing? Once you’ve answered that, you can start addressing the writing itself. First, break up your paragraphs into individual sentences. Then, go back and make each sentence as short and punchy as possible. To go even further, you can start each sentence the same way — like with a verb — or add section headers to break up the copy. Or, to put it another way:

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                Break up your paragraphs into individual sentences.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                Make each sentence as short and punchy as possible.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                Start each sentence the same way — like with a verb.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                Keep other options in mind too. Sometimes it might be better to get your point across with a video or animation. You might also put a short answer first and expand on it elsewhere. That way, you’re helping people who are new to your app while offering a richer option for those who want to dive a little deeper.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                What’s your advice for explaining technical concepts in simple terms?

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                First, remember that not everyone will have your level of understanding. Sometimes we get so excited about technical details that we forget the folks who might be using an app for the first time.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                Try explaining the concept to a friend or colleague first — or ask an engineer to give you a quick summary of a feature.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                From there, break down your idea into smaller components and delete anything that isn’t absolutely necessary. Technical concepts can feel even more intimidating when delivered in a big block of text. Can you link to a support page? Do people need that information in this particular moment? Offering small bits of information is always a good first step.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                How can I harness the “less is more” concept without leaving people confused?

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                Clarity should always be the priority. The trick is to make something as long as it needs to be, but as short as it can be. Start by writing everything down — and then putting it away for a few days. When you come back to it, you’ll have a clearer perspective on what can be cut.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                One more tip: Look for clusters of short words — those usually offer opportunities to tighten things up.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                How should I think about writing my onboarding?

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                Naturally, this will depend on your app or game — you’ll have to figure out what’s necessary and right for you. But typically, brevity is key when it comes to text — especially at the beginning, when people are just trying to get into the experience.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                Consider providing a brief overview of high-level features so people know why they should use your app and what to expect while doing so. Also, think about how they got there. What text did they see before opening your app? What text appeared on the App Store? All of this contributes to the overall journey.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                Human Interface Guidelines: Onboarding

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                Should UX writing have a personal tone? Or does that make localization too difficult?

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                When establishing your voice and tone, you should absolutely consider adding elements of personality to get the elusive element of “character.” But you're right to consider how your strings will localize. Ideally, you’ll work with your localization partners for this. Focus on phrases that strike the tone you want without resorting to idioms. And remember that a little goes a long way.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                How should I approach writing inclusively, particularly in conveying gender?

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                This is an incredibly important part of designing for everyone. Consider whether specifying gender is necessary for the experience you’re creating. If gender is necessary, it’s helpful to provide a full set of options — as well as an option to decline the question. Many things can be written without alluding to gender at all and are thus more inclusive. You can also consider using glyphs. SF Symbols provides lots of inclusive options. And you can find more guidance about writing inclusively in the Human Interface Guidelines.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                Human Interface Guidelines: Inclusion

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                What are some best practices for writing helpful notifications?

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                First, keep in mind that notifications can feel inherently interruptive — and that people receive lots of them all day long. Before you write a notification at all, ask yourself these questions:

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                • Does the message need to be sent right now?
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                • Does the message save someone from opening your app?
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                • Does the message convey something you haven’t already explained?

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                If you answered yes to all of the above, learn more about notification best practices in the Human Interface Guidelines.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                Human Interface Guidelines: Notifications

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                Can you offer guidance on writing for the TipKit framework?

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                With TipKit — which displays tips that help people discover features in your app — concise writing is key. Use tips to highlight a brand-new feature in your app, help people discover a hidden feature, or demonstrate faster ways to accomplish a task. Keep your tips to just one idea, and be as clear as possible about the functionality or feature you’re highlighting.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                What’s one suggestion you would give writers to improve their content?

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                One way we find the perfect (or near-perfect) sentence is to show it to other people, including other writers, designers, and creative partners. If you don’t have that option, run your writing by someone else working on your app or even a customer. And you can always read out loud to yourself — it’s an invaluable way to make your writing sound conversational, and a great way to find and cut unnecessary words.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                Hello Developer: February 2024

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  Welcome to the first Hello Developer of the spatial computing era. In this edition: Join us to celebrate International Women’s Day all over the world, find out how the Fantastical team brought their app to life on Apple Vision Pro, get UX writing advice straight from Apple experts, and catch up on the latest news and documentation.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  FEATURED

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  Join us for International Women's Day celebrations

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  This March, we’re honoring International Women’s Day with developer activities all over the world. Celebrate and elevate women in app development through a variety of sessions, panels, and performances.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  FEATURED

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  “The best version we’ve ever made”: Fantastical comes to Apple Vision Pro

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  The best-in-class calendar app Fantastical has 11 years of history, a shelf full of awards, and plenty of well-organized fans on iPad, iPhone, Mac, and Apple Watch. Yet Fantastical’s Michael Simmons says the app on Apple Vision Pro is “the best version we’ve ever made.” Find out what Simmons learned while building for visionOS — and what advice he’d give fellow developers bringing their apps to Apple Vision Pro.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  “The best version we’ve ever made”: Fantastical comes to Apple Vision Pro View now

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  Q&A

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  Get advice from the Apple UX writing team

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  Writing is fundamental — especially in your apps and games, where the right words can have a profound impact on your app’s experience. During WWDC23, the Apple UX writing team hosted a wide-ranging Q&A that covered everything from technical concepts to inspiring content to whether apps should have “character.”

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  Q&A with the Apple UX writing team View now

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  NEWS

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  Download the Apple Developer app on visionOS

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  Apple Developer has come to Apple Vision Pro. Experience a whole new way to catch up on WWDC videos, browse news and features, and stay up to date on the latest Apple frameworks and technologies.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  Download Apple Developer from the App Store

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  VIDEOS

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  Dive into Xcode Cloud, Apple Pay, and network selection

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  This month’s new videos cover a lot of ground. Learn how to connect your source repository with Xcode Cloud, find out how to get started with Apple Pay on the Web, and discover how your app can automatically select the best network for an optimal experience.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  Connect your project to Xcode Cloud Watch now Get started with Apple Pay on the Web Watch now Adapt to changing network conditions Watch now

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  BEHIND THE DESIGN

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  Rebooting an inventive puzzle game for visionOS

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  Bringing the mind-bending puzzler Blackbox to Apple Vision Pro presented Ryan McLeod with a challenge and an opportunity like nothing he'd experienced before. Find out how McLeod and team are making the Apple Design Award-winning game come to life on the infinite canvas. Then, catch up on our Apple Vision Pro developer interviews and Q&As with Apple experts.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  Blackbox: Rebooting an inventive puzzle game for visionOS View now Apple Vision Pro developer stories and Q&As View now

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  MEET WITH APPLE EXPERTS

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  Sign up for developer activities

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  This month, you can learn to minimize churn and win back subscribers in an online session hosted by App Store experts, and meet with App Review to explore best practices for a smooth review process. You can also request to attend an in-person lab in Cork, Ireland, to help develop your alternative app marketplace on iOS in the European Union. View the full schedule of activities.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  DOCUMENTATION

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  Explore and create with new and updated docs

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  View the full list of new resources.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  Discover what’s new in the Human Interface Guidelines.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  NEWS

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  Catch up on the latest updates
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  • Swift Student Challenge applications are open: Learn about past Challenge winners and get everything you need to create an awesome app playground.
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  • App Store Connect API 3.2: Manage your apps on the App Store for Apple Vision Pro and download new Sales and Trends install reports, including information about historical first annual installs.
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  • New StoreKit entitlement: If your app offers in-app purchases on the App Store for iPhone or iPad in the United States, you can include a link to your website to let people know of other ways to purchase your digital goods or services.
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  • New reports and sign-in options: You’ll soon be able to view over 50 new reports to help measure your apps’ performance. And you can take advantage of new flexibility when asking users to sign in to your app.
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  • App distribution in the European Union: We’re sharing some changes to iOS, Safari, and the App Store, impacting developers’ apps in the EU to comply with the Digital Markets Act.
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  • App Store Review Guideline update: Check out the latest changes to support updated policies and provide clarification.
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  Subscribe to Hello Developer

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  Want to get Hello Developer in your inbox? Make sure you’ve opted in to receive emails about developer news and events by updating your email preferences in your developer account.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  Share your thoughts

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  We’d love to hear from you. If you have suggestions for our activities or stories, please let us know.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  “The best version we’ve ever made”: Fantastical comes to Apple Vision Pro

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    The best-in-class calendar app Fantastical has more than a decade of history, a shelf full of awards, and plenty of well-organized fans on iPad, iPhone, Mac, and Apple Watch. Yet Michael Simmons, CEO and lead product designer for Flexibits, the company behind Fantastical, says the Apple Vision Pro app is “the best version we’ve ever made.” We asked Simmons about what he’s learned while building for visionOS, his experiences visiting the developer labs, and what advice he’d give fellow developers bringing their apps to Vision Pro.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    What was your initial approach to bringing Fantastical from iPad to Apple Vision Pro?

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    The first thing we did was look at the platform to see if a calendar app made sense. We thought: “Could we do something here that’s truly an improvement?” When the answer was yes, we moved on to, “OK, what are the possibilities?” And of course, visionOS gives you unlimited possibilities. You’re not confined to borders; you have the full canvas of the world to create on.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    We wanted to take advantage of that infinite canvas. But we also needed to make sure Fantastical felt right at home in visionOS. People want to feel like there’s a human behind the design — especially in our case, where some customers have been with us for almost 13 years. There’s a legacy there, and an expectation that what you’ll see will feel connected to what we’ve done for more than a decade.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    I play guitar, so to me it felt like learning an instrument.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    Michael Simmons, CEO and lead product designer for Flexibits

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    In the end, it all felt truly seamless, so much so that once Fantastical was finished, we immediately said, “Well, let’s do [the company’s contacts app] Cardhop too!”

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    Was there a moment when you realized, “We’ve really got something here”?

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    It happened as instantly as it could. I play guitar, so to me it felt like learning an instrument. One day it just clicks — the songs, the notes, the patterns — and feels like second nature. For me, it felt like those movies where a musical prodigy feels the music flowing out of them.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    How did you approach designing for visionOS?

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    We focused a lot on legibility of the fonts, buttons, and other screen elements. The opaque background didn’t play well with elements from other operating systems, for example, so we tweaked it. We stayed consistent with design language, used system-provided colors as much as possible, built using mainly UIKit, and used SwiftUI for ornaments and other fancy Vision Pro elements. It’s incredible how great the app looked without us needing to rewrite a bunch of code.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    How long did the process take?

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    It was five months from first experiencing the device to submitting a beautiful app. Essentially, that meant three months to ramp up — check out the UI, explore what was doable, and learn the tools and frameworks — and two more months to polish, refine, and test. That’s crazy fast! And once we had that domain knowledge, we were able to do Cardhop in two months. So I’d say if you have an iPad app and that knowledge, it takes just months to create a Apple Vision Pro version of your app.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    What advice would you give to other developers looking to bring their iPhone or iPad apps to Apple Vision Pro?

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    Make sure your app is appropriate for the platform. Look at the device — all of its abilities and possibilities — and think about how your app would feel with unlimited real estate. And if your app makes sense — and most apps do make sense — and you’re already developing for iPad, iPhone, or Mac, it’s a no-brainer to bring it to Apple Vision Pro.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    Download Fantastical from the App Store

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    Updates to support app distribution changes in the European Union

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      We recently announced changes to iOS, Safari, and the App Store impacting developers’ apps in the European Union (EU) to comply with the Digital Markets Act (DMA), supported by more than 600 new APIs, a wide range of developer tools, and related documentation.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      And we’re continuing to provide new ways for developers to understand and utilize these changes, including:

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      • Online consultations to discuss alternative distribution on iOS, alternative payments on the App Store, linking out to purchase on their webpage, new business terms, and more.
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      • Labs to help develop alternative app marketplaces on iOS.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      Developers who have agreed to the new business terms can now use new features in App Store Connect and the App Store Connect API to set up marketplace distribution and marketplace apps, and use TestFlight to beta test these features. TestFlight also supports apps using alternative browser engines, and alternative payments through payment service providers and linking out to a webpage.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      And soon, you’ll be able to view expanded app analytics reports for the App Store and iOS.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      App Store Connect upload requirement starts April 29

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        Apps uploaded to App Store Connect must be built with Xcode 15 for iOS 17, iPadOS 17, tvOS 17, or watchOS 10, starting April 29, 2024.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        Learn about submitting your apps

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        Apply for the Swift Student Challenge now through February 25

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          Every year, the Swift Student Challenge aims to inspire students to create amazing app playgrounds that can make life better for their communities — and beyond.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          Have an app idea that’s close to your heart? Now’s your chance to make it happen. Build an app playground and submit by February 25.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          All winners receive a year of complimentary membership in the Apple Developer Program and other exclusive awards. And for the first time ever, we’ll award a select group of Distinguished Winners a trip to Apple Park for an incredible in-person experience.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          Apply now

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          Request a consultation about the changes to apps distributed in the European Union

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            Meet with an Apple team member to discuss changes to iOS, Safari, and the App Store impacting apps in the European Union to comply with the Digital Markets Act. Topics include alternative distribution on iOS, alternative payments in the App Store, linking out to purchase on your webpage, new business terms, and more.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            Request a 30-minute online consultation to ask questions and provide feedback about these changes.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            In addition, if you’re interested in getting started with operating an alternative app marketplace on iOS in the European Union, you can request to attend an in-person lab in Cork, Ireland.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            Blackbox: Rebooting an inventive puzzle game for visionOS

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              If you’ve ever played Blackbox, you know that Ryan McLeod builds games a little differently.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              In the inventive iOS puzzler from McLeod’s studio, Shapes & Stories, players solve challenges not by tapping or swiping but by rotating the device, plugging in the USB cable, singing a little tune — pretty much everything except touching the screen.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              “The idea was to get people in touch with the world outside their device,” says McLeod, while ambling along the canals of his Amsterdam home base.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              I’m trying to figure out what makes Blackbox tick on iOS, and how to bring that to visionOS. That requires some creative following of my own rules — and breaking some of them.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              Ryan McLeod

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              In fact, McLeod freed his puzzles from the confines of a device screen well before Apple Vision Pro was even announced — which made bringing the game to this new platform a fascinating challenge. On iOS and iPadOS, Blackbox plays off the familiarity of our devices. But how do you transpose that experience to a device people haven’t tried yet? And how do you break boundaries on a canvas that doesn’t have any? “I do love a good constraint,” says McLeod, “but it has been fun to explore the lifting of that restraint. I’m trying to figure out what makes Blackbox tick on iOS, and how to bring that to visionOS. That requires some creative following of my own rules — and breaking some of them.”

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              After a brief onboarding, the game becomes an all-new visionOS experience that takes advantage of the spatial canvas right from the first level selection. “I wanted something a little floaty and magical, but still grounded in reality,” he says. “I landed on the idea of bubbles. They’re like soap bubbles: They’re natural, they have this hyper-realistic gloss, and they move in a way you’re familiar with. The shader cleverly pulls the reflection of your world into them in this really believable, intriguing way.”

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              And the puzzles within those bubbles? “Unlike Blackbox on iOS, you’re not going to play this when you’re walking home from school or waiting in line,” McLeod says. “It had to be designed differently. No matter how exciting the background is, or how pretty the sound effects are, it’s not fun to just stare at something, even if it’s bobbing around really nicely.”

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              Ryan McLeod’s notebook shows pen sketches of what will become Blackbox on Apple Vision Pro.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              Now, McLeod cautions that Blackbox is still very much a work in progress, and we’re certainly not here to offer any spoilers. But if you want to go in totally cold, it might be best to skip this next part.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              In Blackbox, players interact with the space — and their own senses — to explore and solve challenges. One puzzle involves moving your body in a certain manner; another involves sound, silence, and a blob of molten gold floating like an alien in front of you. A second puzzle involves Morse code. And solving a third puzzle causes part of the scene to collapse into a portal. “Spatial Audio makes the whole thing kind of alarming but mesmerizing,” he says.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              There's an advantage to not knowing expected or common patterns.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              Ryan McLeod

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              It's safe to say Blackbox will continue evolving, especially since McLeod is essentially building this plane as he’s flying it — something he views as a positive. “There’s an advantage to not knowing expected or common patterns,” he says. “There’s just so much possibility.”

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              Download Blackbox for Vision from the App Store

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              Apple Vision Pro developer stories and Q&amp;As

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                Meet some of the incredible teams building for visionOS, and get answers from Apple experts on spatial design and creating great apps for Apple Vision Pro.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                Developer stories “The best version we’ve ever made”: Fantastical comes to Apple Vision Pro View now Blackbox: Rebooting an inventive puzzle game for visionOS View now “The full impact of fruit destruction”: How Halfbrick cultivated Super Fruit Ninja on Apple Vision Pro View now Realizing their vision: How djay designed for visionOS View now JigSpace is in the driver’s seat View now PTC is uniting the makers View now Q&As Q&A: Spatial design for visionOS View now Q&A: Building apps for visionOS View now

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                Price and tax updates for apps, in-app purchases, and subscriptions

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  The App Store is designed to make it easy to sell your digital goods and services globally, with support for 44 currencies across 175 storefronts.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  From time to time, we may need to adjust prices or your proceeds due to changes in tax regulations or foreign exchange rates. These adjustments are made using publicly available exchange rate information from financial data providers to help ensure that prices for apps and in-app purchases remain consistent across all storefronts.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  Price updates

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  On February 13, pricing for apps and in-app purchases* will be updated for the Benin, Colombia, Tajikistan, and Türkiye storefronts. Also, these updates consider the following tax changes:

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  • Benin: value-added tax (VAT) introduction of 18%
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  • Tajikistan: VAT rate decrease from 15% to 14%

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  Prices will be updated on the Benin, Colombia, Tajikistan, and Türkiye storefronts if you haven’t selected one of these as the base for your app or in‑app purchase.*

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  Prices won’t change on the Benin, Colombia, Tajikistan, or Türkiye storefront if you’ve selected that storefront as the base for your app or in-app purchase.* Prices on other storefronts will be updated to maintain equalization with your chosen base price.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  Prices won’t change in any region if your in‑app purchase is an auto‑renewable subscription and won’t change on the storefronts where you manually manage prices instead of using the automated equalized prices.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  The Pricing and Availability section of My Apps has been updated in App Store Connect to display these upcoming price changes. As always, you can change the prices of your apps, in‑app purchases, and auto‑renewable subscriptions at any time.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  Learn more about managing your prices

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  View or edit upcoming price changes

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  Edit your app’s base country or region

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  Pricing and availability start times by region

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  Set a price for an in-app purchase

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  Tax updates

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  Your proceeds for sales of apps and in-app purchases will change to reflect the new tax rates and updated prices. Exhibit B of the Paid Applications Agreement has been updated to indicate that Apple collects and remits applicable taxes in Benin.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  On January 30, your proceeds from the sale of eligible apps and in‑app purchases were modified in the following countries to reflect introductions or changes in VAT rates.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  • Benin: VAT introduction of 18%
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  • Czechia: VAT rate decreased from 10% to 0% for certain eBooks and audiobooks
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  • Czechia: VAT rate increased from 10% to 12% for certain eNewspapers and Magazines
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  • Estonia: VAT rate increased from 20% to 22%
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  • Ireland: VAT rate decreased from 9% to 0% for certain eBooks and audiobooks
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  • Luxembourg: VAT rate increased from 16% to 17%
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  • Singapore: GST rate increased from 8% to 9%
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  • Switzerland: VAT rate increased from 2.5% to 2.6% for certain eNewspapers, magazines, books and audiobooks
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  • Switzerland: VAT rate increased from 7.7% to 8.1% for all other apps and in-app purchases
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  • Tajikistan: VAT rate decreased from 15% to 14%
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  Learn more about your proceeds

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  View payments and proceeds

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  Download financial reports

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  *Excludes auto-renewable subscriptions.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  Get ready with the latest beta releases

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    The beta versions of iOS 17.4, iPadOS 17.4, macOS 14.4, tvOS 17.4, and watchOS 10.4 are now available. Get your apps ready by confirming they work as expected on these releases. And to take advantage of the advancements in the latest SDKs, make sure to build and test with Xcode 15.3 beta.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    View downloads and release notes

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    Learn about testing a beta OS

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    Learn about sending feedback

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    Apple introduces new options worldwide for streaming game services and apps that provide access to mini apps and games

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      New analytics reports coming in March for developers everywhere

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      Developers can also enable new sign-in options for their apps

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      Today, Apple is introducing new options for how apps globally can deliver in-app experiences to users, including streaming games and mini-programs. Developers can now submit a single app with the capability to stream all of the games offered in their catalog.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      Apps will also be able to provide enhanced discovery opportunities for streaming games, mini-apps, mini-games, chatbots, and plug-ins that are found within their apps.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      Additionally, mini-apps, mini-games, chatbots, and plug-ins will be able to incorporate Apple’s In-App Purchase system to offer their users paid digital content or services for the first time, such as a subscription for an individual chatbot.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      Each experience made available in an app on the App Store will be required to adhere to all App Store Review Guidelines and its host app will need to maintain an age rating of the highest age-rated content included in the app.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      The changes Apple is announcing reflect feedback from Apple’s developer community and is consistent with the App Store’s mission to provide a trusted place for users to find apps they love and developers everywhere with new capabilities to grow their businesses. Apps that host this content are responsible for ensuring all the software included in their app meets Apple’s high standards for user experience and safety.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      New app analytics

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      Apple provides developers with powerful dashboards and reports to help them measure their apps’ performance through App Analytics, Sales and Trends, and Payments and Financial Reports. Today, Apple is introducing new analytics for developers everywhere to help them get even more insight into their businesses and their apps’ performance, while maintaining Apple’s long-held commitment to ensure users are not identifiable at an individual level.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      Over 50 new reports will be available through the App Store Connect API to help developers analyze their app performance and find opportunities for improvement with more metrics in areas like:

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      Engagement — with additional information on the number of users on the App Store interacting with a developer’s app or sharing it with others;

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      Commerce — with additional information on downloads, sales and proceeds, pre-orders, and transactions made with the App Store’s secure In-App Purchase system;

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      App usage — with additional information on crashes, active devices, installs, app deletions, and more.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      Frameworks usage — with additional information on an app’s interaction with OS functionality such as PhotoPicker, Widgets, and CarPlay.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      Additional information about report details and access will be available for developers in March.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      Developers will have the ability to grant third-party access to their reports conveniently through the API.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      More flexibility for sign in options in apps

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      In line with Apple’s mission to protect user privacy, Apple is updating its App Store Review Guideline for using Sign in with Apple. Sign in with Apple makes it easy for users to sign in to apps and websites using their Apple ID and was built from the ground up with privacy and security in mind. Starting today, developers that offer third-party or social login services within their app will have the option to offer Sign in with Apple, or they will now be able to offer an equivalent privacy-focused login service instead.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      Update on apps distributed in the European Union

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        We’re sharing some changes to iOS, Safari, and the App Store, impacting developers’ apps in the European Union (EU) to comply with the Digital Markets Act (DMA). These changes create new options for developers who distribute apps in any of the 27 EU member states, and do not apply to apps distributed anywhere else in the world. These options include how developers can distribute apps on iOS, process payments, use web browser engines in iOS apps, request interoperability with iPhone and iOS hardware and software features, access data and analytics about their apps, and transfer App Store user data.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        If you want nothing to change for you — from how the App Store works currently in the EU and in the rest of the world — no action is needed. You can continue to distribute your apps only on the App Store and use its private and secure In-App Purchase system.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        Learn about the updates

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        Updated App Store Review Guidelines now available

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          The App Store Review Guidelines have been revised to support updated policies, upcoming features, and to provide clarification. We now also indicate which guidelines only apply to Notarization for iOS apps in the European Union.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          The following guidelines have been divided into subsections for the purposes of Notarization for iOS apps in the EU:

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          • 2.3.1
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          • 2.5.16
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          • 4.1
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          • 4.3
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          • 4.6
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          • 5.1.4
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          • 5.2.4

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          The following guidelines have been deleted:

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          • 2.5.7
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          • 3.2.2(vi)
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          • 4.2.4
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          • 4.2.5
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          • 4.4.3

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          2.5.6: Added a link to an entitlement to use an alternative web browser engine in your app in the EU.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          3.1.6: Moved to 4.9.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          3.2.2(ii): Moved to 4.10.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          4.7: Edited to set forth new requirements for mini apps, mini games, streaming games, chatbots, and plug-ins.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          4.8: Edited to require an additional login service with certain privacy features if you use a third-party or social login service to set up or authenticate a user’s primary account.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          4.9: The original version of this rule (Streaming games) has been deleted and replaced with the Apple Pay guideline.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          5.1.2(i): Added that apps may not require users to enable system functionalities (e.g., push notifications, location services, tracking) in order to access functionality, content, use the app, or receive monetary or other compensation, including but not limited to gift cards and codes. A version of this rule was originally published as Guideline 3.2.2(vi).

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          After You Submit — Appeals: Edited to add an updated link for suggestions for changes to the Guidelines.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          The term “auto-renewing subscriptions” was replaced with “auto-renewable subscriptions” throughout.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          View guidelines

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          Translations of the guidelines will be available on the Apple Developer website within one month.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          Swift Student Challenge applications open February 5

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            We’re so excited applications for the Swift Student Challenge 2024 will open on February 5.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            Looking for some inspiration? Learn about past Challenge winners to gain insight into the motivations behind their apps.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            Just getting started? Get tools, tips, and guidance on everything you need to create an awesome app playground.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            “The full impact of fruit destruction”: How Halfbrick cultivated Super Fruit Ninja on Apple Vision Pro

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              Fruit Ninja has a juicy history that stretches back more than a decade, but Samantha Turner, lead gameplay programmer at the game’s Halfbrick Studios, says the Apple Vision Pro version — Super Fruit Ninja on Apple Arcade — is truly bananas. “When it first came out, Fruit Ninja kind of gave new life to the touchscreen,” she notes, “and I think we have the potential to do something very special here.”

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              What if players could squeeze juice out of an orange? What if they could rip apart a watermelon and cover the table and walls with juice?

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              Samantha Turner, lead gameplay programmer at Halfbrick Studios

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              Turner would know. She’s worked on the Fruit Ninja franchise for nearly a decade, which makes her especially well suited to help grow the game on a new platform. “We needed to understand how to bring those traditional 2D user interfaces into the 3D space,” she says. “We were full of ideas: What if players could squeeze juice out of an orange? What if they could rip apart a watermelon and cover the table and walls with juice?” She laughs, on a roll. “We were really playing with the environment.”

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              But they also needed to get people into that environment. “That’s where we came up with the flying menu,” she says, referring to the old-timey home screen that’ll feel familiar to Fruit Ninja fans, except for how it hovers in space. “We wanted a friendly and welcoming way to bring people into the immersive space,” explains Turner. “Before we landed on the menu, we were doing things like generating 3D text to put on virtual objects. But that didn’t give us the creative freedom we needed to set the theme for our world.”

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              To create Super Fruit Ninja, the Halfbrick team worked to bring “traditional 2D interfaces into the 3D space.”

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              That theme: The good citizens of Fruitasia have discovered a portal to our world — one that magically materializes in the room. “Sensei steps right through the portal,” says Turner, “and you can peek back into their world too.”

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              Next, Turner and Halfbrick set about creating a satisfying — and splashy — way for people to interact with their space. The main question: What’s the most logical way to launch fruit at people?

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              “We started with, OK, you have a couple meters square in front of you. What will the playspace look like? What if there’s a chair or a table in the way? How do we work around different scenarios for people in their office or living room or kitchen?” To find their answers, Halfbrick built RealityKit prototypes. “Just being able to see those really opened up the possibilities.” The answer? A set of cannons, arranged in a semicircle at the optimal distance for efficient slashing.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              Instead of holding blades, you simply use your hands.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              Samantha Turner, lead gameplay programmer at Halfbrick Studios

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              It also let them move onto the question of how players can carve up a bunch of airborne bananas in a 3D space. The team experimented with a variety of hand motions, but none felt as satisfying as the final result. “Instead of holding blades, you simply use your hands,” she says. “You become the weapon.”

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              And you’re a powerful weapon. Slice and dice pineapples and watermelons by jabbing with your hands. Send bombs away by pushing them to a far wall, where they harmlessly explode at a distance. Fire shuriken into floating fruit by brushing your palms in an outward direction — a motion Turner particularly likes. “It’s satisfying to see it up close, but when you see it happen far away, you get the full impact of fruit destruction,” she laughs. All were results of hand gesture explorations.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              Truffles the pig awaits his reward in Super Fruit Ninja.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              “We always knew hands would be the center of the experience,” she says. “We wanted players to be able to grab things and knock them away. And we can tailor the arc of the fruit to make sure it's a comfortable fruit-slicing experience — we’re actually using the vertical position of the device itself to make sure that we're not throwing fruit over your head or too low.”

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              The result is the most immersive — and possibly most entertaining — Fruit Ninja to date, not just for players but for the creators. “Honestly,” Turner says, “this version is one of my favorites.”

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              Find Super Fruit Ninja on Apple Arcade

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              StoreKit and review guideline update

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                Starting today, because of a recent United States Court decision, App Store Review Guideline 3.1.1 has been updated to introduce the StoreKit Purchase Link Entitlement (US), which allows apps that offer in-app purchases in the iOS or iPadOS App Store on the United States storefront the ability to include a link to the developer’s website that informs users of other ways to purchase digital goods or services.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                We believe Apple’s in-app purchase system is the most convenient, safe, and secure way for users to purchase digital goods and services. If you’re considering using this entitlement along with in‑app purchase, which continues to be required for the purchase of digital goods and services within your app — it’s important to understand that some App Store features, such as Ask to Buy or Family Sharing, won’t be available to your customers when they make purchases on your website. Apple also won’t be able to assist customers with refunds, purchase history, subscription management, and other issues encountered when purchasing digital goods and services. You will be responsible for addressing such issues with customers.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                A commission will apply to digital purchases facilitated through the StoreKit Purchase Link Entitlement (US). For additional details on commissions, requesting the entitlement, usage guidelines, and implementation details, view our support page.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                Realizing their vision: How djay designed for visionOS

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  Years ago, early in his professional DJ career, Algoriddim cofounder and CEO Karim Morsy found himself performing a set atop a castle tower on the Italian coast. Below him, a crowd danced in the ruins; before him streched a moonlit-drenched coastline and the Mediterranean Sea. “It was a pretty inspiring environment,” Morsy says, probably wildly underselling this.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  Through their app djay, Morsy and Algoriddim have worked to recreate that live DJ experience for nearly 20 years. The best-in-class DJ app started life as boxed software for Mac; subsequent versions for iPad offered features like virtual turntables and beat matching. The app was a smashing success that won an Apple Design Award in both 2011 and 2016.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  On Apple Vision Pro, djay transports people to a number of inventive immersive environments.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  But Morsy says all that previous work was prologue to djay on the infinite canvas. “When we heard about Apple Vision Pro,” he says, “it felt like djay was this beast that wanted to be unleashed. Our vision — no pun intended — with Algoriddim was to make DJing accessible to everyone,” he says. Apple Vision Pro, he says, represents the realization of that dream. “The first time I experienced the device was really emotional. I wanted to be a DJ since I was a child. And suddenly here were these turntables, and the night sky, and the stars above me, and this light show in the desert. I felt like, ‘This is the culmination of everything. This is the feeling I’ve been wanting people to experience.’”

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  When we heard about Apple Vision Pro, it felt like djay was this beast that wanted to be unleashed.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  Karim Morsy, Algoriddim cofounder and CEO

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  Getting to that culmination necessitated what Morsy calls “the wildest sprint of our lives.” With a 360-degree canvas to explore, the team rethought the entire process of how people interacted with djay. “We realized that with a decade of building DJ interfaces, we were taking a lot for granted,” he says. “So the first chunk of designing for Apple Vision Pro was going back to the drawing board and saying, ‘OK, maybe this made sense 10 years ago with a computer and mouse, but why do we need it now? Why should people have to push a button to match tempos — shouldn’t that be seamless?’ There was so much we could abstract away.”

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  Spin in a fully immersive environment, or bring your two turntables into the room with you.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  They also thought about environments. djay offers a windowed view, a shared space that brings 3D turntables into your environment, and several forms of full immersion. The app first opens to the windowed view, which should feel familiar to anyone who’s spun on the iPad app: a simple UI of two decks. The volumetric view brings into your room not just turntables, but the app’s key moment: the floating 3D cube that serves as djay’s effects control pad.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  But those immersive scenes are where Morsy feels people can truly experience reacting to and feeding off the environment. There’s an LED wall that reflects colors from the artwork of the currently playing song, a nighttime desert scene framed by an arena of lights, and a space lounge — complete with dancing robots — that offers a great view of planet Earth. The goal of those environments is to help create the “flow state” that’s sought by live DJs. “You want to get into a loop where the environment influences you and vice versa,” Morsy says.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  From left: Algoriddim’s Karim Morsy, Frederik Seiffert, and Federico Tessmann work on updates to their app with the proper equipment.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  In the end, this incredible use of technology serves a very simple purpose: interacting with the music you love. Morsy — a musician himself — points to a piano he keeps in his office. “That piano has had the same interface for hundreds of years,” he says. “That’s what we’re trying to reach, that sweet spot between complexity and ease of use. With djay on Vision Pro, it’s less about, ‘Let’s give people bells and whistles,’ and more, ‘Let’s let them have this experience.’”

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  Download djay from the App Store

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  Hello Developer: January 2024

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    Welcome to Hello Developer. In this Apple Vision Pro-themed edition: Find out how to submit your visionOS apps to the App Store, learn how the team behind djay approached designing for the infinite canvas, and get technical answers straight from Apple Vision Pro engineers. Plus, catch up on the latest news, documentation, and developer activities.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    FEATURED

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    Submit your apps to the App Store for Apple Vision Pro

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    Apple Vision Pro will have a brand-new App Store, where people can discover and download all the incredible apps available for visionOS. Whether you’ve created a new visionOS app or are making your existing iPad or iPhone app available on Apple Vision Pro, here’s everything you need to know to prepare and submit your app to the App Store.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    BEHIND THE DESIGN

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    Realizing their vision: How djay designed for visionOS

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    Algoriddim CEO Karim Morsy says Apple Vision Pro represents “the culmination of everything” for his app, djay. In the latest edition of Behind the Design, find out how this incredible team approached designing for the infinite canvas.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    Realizing their vision: How djay designed for visionOS View now

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    Q&A

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    Get answers from Apple Vision Pro engineers

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    In this Q&A, Apple Vision Pro engineers answer some of the most frequently asked questions from Apple Vision Pro developer labs all over the world.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    Q&A: Building apps for visionOS View now

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    COLLECTION

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    Reimagine your enterprise apps on Apple Vision Pro

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    Discover the languages, tools, and frameworks you’ll need to build and test your apps for visionOS. Explore videos and resources that showcase productivity and collaboration, simulation and training, and guided work. And dive into workflows for creating or converting existing media, incorporating on-device and remote assets into your app, and much more.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    Reimagine your enterprise apps on Apple Vision Pro View now

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    MEET WITH APPLE EXPERTS

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    Submit your request for developer labs and App Review consultations

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    Join us this month in the Apple Vision Pro developer labs to get your apps ready for visionOS. With help from Apple, you’ll be able to test, refine, and finalize your apps and games. Plus, Apple Developer Program members can check out one-on-one App Review, design, and technology consultations, offered in English, Spanish, Brazilian Portuguese, and more.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    DOCUMENTATION

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    Check out visionOS sample apps, SwiftUI tutorials, audio performance updates, and more

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    These visionOS sample apps feature refreshed audio, visual, and timing elements, simplified collision boxes, and performance improvements.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    • Hello World: Use windows, volumes, and immersive spaces to teach people about the Earth.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    • Happy Beam: Leverage a Full Space to create a game using ARKit.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    • Diorama: Design scenes for your visionOS app using Reality Composer Pro.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    • Swift Splash: Use RealityKit to create an interactive ride in visionOS.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    And these resources and updated tutorials cover iOS 17, accessibility, Live Activities, and audio performance.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    View the full list of new resources.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    Discover what’s new in the Human Interface Guidelines.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    NEWS

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    Catch up on the latest updates Subscribe to Hello Developer

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    Want to get Hello Developer in your inbox? Make sure you’ve opted in to receive emails about developer news and events by updating your email preferences in your developer account.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    Share your thoughts

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    We’d love to hear from you. If you have suggestions for our activities or stories, please let us know.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    Q&amp;A: Building apps for visionOS

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      Over the past few months, Apple experts have fielded questions about visionOS in Apple Vision Pro developer labs all over the world. Here are answers to some of the most frequent questions they’ve been asked, including insights on new concepts like entities, immersive spaces, collision shapes, and much more.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      How can I interact with an entity using gestures?

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      There are three important pieces to enabling gesture-based entity interaction:

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      1. The entity must have an InputTargetComponent. Otherwise, it won’t receive gesture input at all.
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      2. The entity must have a CollisionComponent. The shapes of the collision component define the regions that gestures can actually hit, so make sure the collision shapes are specified appropriately for interaction with your entity.
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      3. The gesture that you’re using must be targeted to the entity you’re trying to interact with (or to any entity). For example:
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      private var tapGesture: some Gesture {
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          TapGesture()
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              .targetedToAnyEntity()
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              .onEnded { gestureValue in
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  let tappedEntity = gestureValue.entity
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  print(tappedEntity.name)
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              }
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      }

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      It’s also a good idea to give an interactive entity a HoverEffectComponent, which enables the system to trigger a standard highlight effect when the user looks at the entity.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      Should I use a window group, an immersive space, or both?

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      Consider the technical differences between windows, volumes, and immersive spaces when you decide which scene type to use for a particular feature in your app.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      Here are some significant technical differences that you should factor into your decision:

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      1. Windows and volumes from other apps the user has open are hidden when an immersive space is open.
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      2. Windows and volumes clip content that exceeds their bounds.
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      3. Users have full control over the placement of windows and volumes. Apps have full control over the placement of content in an immersive space.
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      4. Volumes have a fixed size, windows are resizable.
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      5. ARKit only delivers data to your app if it has an open immersive space.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      Explore the Hello World sample code to familiarize yourself with the behaviors of each scene type in visionOS.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      How can I visualize collision shapes in my scene?

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      Use the Collision Shapes debug visualization in the Debug Visualizations menu, where you can find several other helpful debug visualizations as well. For information on debug visualizations, check out Diagnosing issues in the appearance of a running app.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      Can I position SwiftUI views within an immersive space?

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      Yes! You can position SwiftUI views in an immersive space with the offset(x:y:) and offset(z:) methods. It’s important to remember that these offsets are specified in points, not meters. You can utilize PhysicalMetric to convert meters to points.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      What if I want to position my SwiftUI views relative to an entity in a reality view?

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      Use the RealityView attachments API to create a SwiftUI view and make it accessible as a ViewAttachmentEntity. This entity can be positioned, oriented, and scaled just like any other entity.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      RealityView { content, attachments in
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          // Fetch the attachment entity using the unique identifier.
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          let attachmentEntity = attachments.entity(for: "uniqueID")!
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          // Add the attachment entity as RealityView content.
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          content.add(attachmentEntity)
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      } attachments: {
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          // Declare a view that attaches to an entity.
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          Attachment(id: "uniqueID") {
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              Text("My Attachment")
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          }
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      }
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      Can I position windows programmatically?

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      There’s no API available to position windows, but we’d love to know about your use case. Please file an enhancement request. For more information on this topic, check out Positioning and sizing windows.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      Is there any way to know what the user is looking at?

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      As noted in Adopting best practices for privacy and user preferences, the system handles camera and sensor inputs without passing the information to apps directly. There's no way to get precise eye movements or exact line of sight. Instead, create interface elements that people can interact with and let the system manage the interaction. If you have a use case that you can't get to work this way, and as long as it doesn't require explicit eye tracking, please file an enhancement request.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      When are the onHover and onContinuousHover actions called on visionOS?

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      The onHover and onContinuousHover actions are called when a finger is hovering over the view, or when the pointer from a connected trackpad is hovering over the view.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      Can I show my own immersive environment textures in my app?

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      If your app has an ImmersiveSpace open, you can create a large sphere with an UnlitMaterial and scale it to have inward-facing geometry:

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      struct ImmersiveView: View {
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          var body: some View {
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              RealityView { content in
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  do {
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      // Create the sphere mesh.
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      let mesh = MeshResource.generateSphere(radius: 10)
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      // Create an UnlitMaterial.
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      var material = UnlitMaterial(applyPostProcessToneMap: false)
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      // Give the UnlitMaterial your equirectangular color texture.
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      let textureResource = try await TextureResource(named: "example")
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      material.color = .init(tint: .white, texture: .init(textureResource))
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      // Create the model.
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      let entity = ModelEntity(mesh: mesh, materials: [material])
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      // Scale the model so that it's mesh faces inward.
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      entity.scale.x *= -1
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      content.add(entity)
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  } catch {
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      // Handle the error.
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  }
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              }
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          }
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      }
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      I have existing stereo videos. How can I convert them to MV-HEVC?

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      AVFoundation provides APIs to write videos in MV-HEVC format. For a full example, download the sample code project Converting side-by-side 3D video to multiview HEV.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      To convert your videos to MV-HEVC:

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      • Create an AVAsset for each of the left and right views.
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      • Use AVOutputSettingsAssistant to get output settings that work for MV-HEVC.
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      • Specify the horizontal disparity adjustment and field of view (this is asset specific). Here’s an example:
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      var compressionProperties = outputSettings[AVVideoCompressionPropertiesKey] as! [String: Any]
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              // Specifies the parallax plane.
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              compressionProperties[kVTCompressionPropertyKey_HorizontalDisparityAdjustment as String] = horizontalDisparityAdjustment
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              // Specifies the horizontal FOV (90 degrees is chosen in this case.)
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              compressionProperties[kCMFormatDescriptionExtension_HorizontalFieldOfView as String] = horizontalFOV
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      // Create a tagged buffer for each stereoView.
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              let taggedBuffers: [CMTaggedBuffer] = [
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  .init(tags: [.videoLayerID(0), .stereoView(.leftEye)], pixelBuffer: leftSample.imageBuffer!),
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  .init(tags: [.videoLayerID(1), .stereoView(.rightEye)], pixelBuffer: rightSample.imageBuffer!)
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              ]
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              // Append the tagged buffers to the asset writer input adaptor.
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              let didAppend = adaptor.appendTaggedBuffers(taggedBuffers,
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          withPresentationTime: leftSample.presentationTimeStamp)
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      How can I light my scene in RealityKit on visionOS?

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      You can light your scene in RealityKit on visionOS by:

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      • Using a system-provided automatic lighting environment that updates based on real-world surroundings.
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      • Providing your own image-based lighting via an ImageBasedLightComponent. To see an example, create a new visionOS app, select RealityKit as the Immersive Space Renderer, and select Full as the Immersive Space.
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      I see that CustomMaterial isn’t supported on visionOS. Is there a way I can create materials with custom shading?

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      You can create materials with custom shading in Reality Composer Pro using the Shader Graph. A material created this way is accessible to your app as a ShaderGraphMaterial, so that you can dynamically change inputs to the shader in your code.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      For a detailed introduction to the Shader Graph, watch Explore materials in Reality Composer Pro.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      How can I position entities relative to the position of the device?

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      In an ImmersiveSpace, you can get the full transform of the device using the queryDeviceAnchor(atTimestamp:) method.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      Learn more about building apps for visionOS Q&A: Spatial design for visionOS View now Spotlight on: Developing for visionOS View now Spotlight on: Developer tools for visionOS View now

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      Sample code contained herein is provided under the Apple Sample Code License.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      Submit your apps to the App Store for Apple Vision Pro

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        Apple Vision Pro will have a brand-new App Store, where people can discover and download incredible apps for visionOS. Whether you’ve created a new visionOS app or are making your existing iPad or iPhone app available on Apple Vision Pro, here’s everything you need to know to prepare and submit your app to the App Store.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        Find out more

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        Updated Apple Developer Program License Agreement now available

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          The Apple Developer Program License Agreement has been revised to support updated policies and provide clarification. The revisions include:

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          • Definitions, Section 3.3.3(N): Updated "Tap to Present ID" to "ID Verifier"

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          • Definitions, Section 14.10: Updated terms regarding governing law and venue

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          • Section 3.3: Reorganized and categorized provisions for clarity

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          • Section 3.3.3(B): Clarified language on privacy and third-party SDKs

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          • Section 6.7: Updated terms regarding analytics

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          • Section 12: Clarified warranty disclaimer language

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          • Attachment 1: Updated terms for use of Apple Push Notification Service and Local Notifications

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          • Attachment 9: Updated terms for Xcode Cloud compute hours included with Apple Developer Program membership

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          View full terms and conditions

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          Announcing contingent pricing for subscriptions

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            Contingent pricing for subscriptions on the App Store — a new feature that helps you attract and retain subscribers — lets you give customers a discounted subscription price as long as they’re actively subscribed to a different subscription. It can be used for subscriptions from one developer or two different developers. We’re currently piloting this feature and will be onboarding more developers in the coming months. If you’re interested in implementing contingent pricing in your app, you can start planning today and sign up to get notified when more details are available in January.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            Learn about contingent pricing and sign up to get notified

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            Get ready with the latest beta releases

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              The beta versions of iOS 17.3, iPadOS 17.3, macOS 14.3, tvOS 17.3, and watchOS 10.3 are now available. Get your apps ready by confirming they work as expected on these releases. And to take advantage of the advancements in the latest SDKs, make sure to build and test with Xcode 15.2 beta.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              View downloads and release notes

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              Learn about testing a beta OS

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              Learn about sending feedback

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              Hello Developer: December 2023

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                Welcome to Hello Developer. In this edition: Check out new videos on Game Center and the Journaling Suggestions API, get visionOS guidance straight from the spatial design team, meet three App Store Award winners, peek inside the time capsule that is Ancient Board Game Collection, and more.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                VIDEOS

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                Manage Game Center with the App Store Connect API

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                In this new video, discover how you can use the App Store Connect API to automate your Game Center configurations outside of App Store Connect on the web.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                Manage Game Center with the App Store Connect API Watch now

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                And find out how the new Journaling Suggestions API can help people reflect on the small moments and big events in their lives through your app — all while protecting their privacy.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                Discover the Journaling Suggestions API Watch now

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                Q&A

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                Get your spatial design questions answered

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                What’s the best way to make a great first impression in visionOS? What’s a “key moment”? And what are some easy methods for making spatial computing visual design look polished? Get answers to these questions and more.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                Q&A: Spatial design for visionOS View now

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                FEATURED

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                Celebrate the winners of the 2023 App Store Awards

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                Every year, the App Store celebrates exceptional apps that improve people’s lives while showcasing the highest levels of technical innovation, user experience, design, and positive cultural impact. Find out how the winning teams behind Finding Hannah, Photomator, and Unpacking approached their incredible work this year.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                “We’re trying to drive change": Meet three App Store Award-winning teams View now

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                Missed the big announcement? Check out the full list of 2023 winners.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                NEWS

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                Xcode Cloud now included with membership

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                Starting January 2024, all Apple Developer Program memberships will include 25 compute hours per month on Xcode Cloud as a standard, with no additional cost. Learn more.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                BEHIND THE DESIGN

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                Travel back in time with Ancient Board Game Collection

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                Klemens Strasser’s Ancient Board Game Collection blends the new and the very, very old. Its games date back centuries: Hnefatafl is said to be nearly 1,700 years old, while the Italian game Latrunculi is closer to 2,000. “I found a book on ancient board games by an Oxford professor and it threw me right down a rabbit hole,” Strasser says. Find out how the Austria-based developer and a team of international artists gave these ancient games new life.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                With Ancient Board Game Collection, Klemens Strasser goes back in time View now

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                DOCUMENTATION

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                Get creative with 3D immersion, games, SwiftUI, and more

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                This month’s new sample code, tutorials, and documentation cover everything from games to passing control between apps to addressing reasons for common crashes. Here are a few highlights:

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                View the full list of new resources.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                View what’s new in the Human Interface Guidelines.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                NEWS

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                Catch up on the latest updates
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                • App Store holiday schedule: We’ll remain open throughout the holiday season and look forward to accepting your submissions. However, reviews may take a bit longer to complete from December 22 to 27.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                • Sandbox improvements: Now you can change a test account’s storefront, adjust subscription renewal rates, clear purchase history, simulate interrupted purchase flows directly on iPhone or iPad, and test Family Sharing.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                • New software releases: Build your apps using the latest developer tools and test them on this week’s OS releases. Download Xcode 15.1 RC, and the RC versions of iOS 17.2, iPadOS 17.2,  macOS 14.2,  tvOS 17.2, and watchOS 10.2.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                Subscribe to Hello Developer

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                Want to get Hello Developer in your inbox? Make sure you’ve opted in to receive emails about developer news and events by updating your email preferences in your developer account.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                Share your thoughts

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                We’d love to hear from you. If you have suggestions for our activities or stories, please let us know.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                Q&amp;A: Spatial design for visionOS

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  Spatial computing offers unique opportunities and challenges when designing apps and games. At WWDC23, the Apple design team hosted a wide-ranging Q&A to help developers explore designing for visionOS. Here are some highlights from that conversation, including insights on the spectrum of immersion, key moments, and sound design.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  What’s the best way to make a great first impression on this platform?

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  While it depends on your app, of course, starting in a window is a great way to introduce people to your app and let them control the amount of immersion. We generally recommend not placing people into a fully immersive experience right away — it’s better to make sure they’re oriented in your app before transporting them somewhere else.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  What should I consider when bringing an existing iPadOS or iOS app to visionOS?

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  Think about a key moment where your app would really shine spatially. For example, in the Photos app for visionOS, opening a panoramic photo makes the image wrap around your field of view. Ask yourself what that potential key moment — an experience that isn’t bound by a screen — is for your app.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  From a more tactical perspective, consider how your UI will need to be optimized for visionOS. To learn more, check out “Design for spatial user interfaces”.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  Design for spatial user interfaces Watch now Can you say a bit more about what you mean by a “key moment”?

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  A key moment is a feature or interaction that takes advantage of the unique capabilities of visionOS. (Think of it as a spatial or immersive highlight in your app.) For instance, if you’re creating a writing app, your key moment might be a focus mode in which you immerse someone more fully in an environment or a Spatial Audio soundscape to get them in the creative zone. That’s just not possible on a screen-based device.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  I often use a grid system when designing for iOS and macOS. Does that still apply here?

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  Definitely! The grid can be very useful for designing windows, and point sizes translate directly between platforms. Things can get more complex when you’re designing elements in 3D, like having nearby controls for a faraway element. To learn more, check out “Principles of spatial design.”

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  Principles of spatial design Watch now What’s the best way to test Apple Vision Pro experiences without the device?

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  You can use the visionOS simulator in Xcode to recreate system gestures, like pinch, drag, tap, and zoom.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  What’s the easiest way to make my spatial computing design look polished?

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  As a starting point, we recommend using the system-provided UI components. Think about hover shapes, how every element appears by default, and how they change when people look directly at them. When building custom components or larger elements like 3D objects, you'll also need to customize your hover effects.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  What interaction or ergonomic design considerations should I keep in mind when designing for visionOS?

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  Comfort should guide experiences. We recommend keeping your main content in the field of view, so people don't need to move their neck and body too much. The more centered the content is in the field of view, the more comfortable it is for the eyes. It's also important to consider how you use input. Make sure you support system gestures in your app so people have the option to interact with content indirectly (using their eyes to focus an element and hand gestures, like a pinch, to select). For more on design considerations, check out “Design considerations for vision and motion.”

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  Design considerations for vision and motion Watch now Are there design philosophies for fully immersive experiences? Should the content wrap behind the person’s head, above them, and below them?

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  Content can be placed anywhere, but we recommend providing only the amount of immersion needed. Apps can create great immersive experiences without taking over people's entire surroundings. To learn more, check out the Human Interface Guidelines.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  Human Interface Guidelines: Immersive experiences

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  Are there guidelines for creating an environment for a fully immersive experience?

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  First, your environment should have a ground plane under the feet that aligns with the real world. As you design the specifics of your environment, focus on key details that will create immersion. For example, you don't need to render all the details of a real theater to convey the feeling of being in one. You can also use subtle motion to help bring an environment to life, like the gentle movement of clouds in the Mount Hood environment.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  What else should I consider when designing for spatial computing?

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  Sound design comes to mind. When designing for other Apple platforms, you may not have placed as much emphasis on creating audio for your interfaces because people often mute sounds on their devices (or it's just not desirable for your current experience). With Apple Vision Pro, sound is crucial to creating a compelling experience.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  People are adept at understanding their surroundings through sound, and you can use sound in your visionOS app or game to help people better understand and interact with elements around them. When someone presses a button, for example, an audio cue helps them recognize and confirm their actions. You can position sound spatially in visionOS so that audio comes directly from the item a person interacts with, and the system can use their surroundings to give it the appropriate reverberation and texture. You can even create spatial soundscapes for scenes to make them feel more lifelike and immersive.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  For more on designing sound for visionOS, check out “Explore immersive sound design.”

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  Explore immersive sound design Watch now Learn more

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  For even more on designing for visionOS, check out more videos, the Human Interface Guidelines, and the Apple Developer website.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  Develop your first immersive app Watch now Get started with building apps for spatial computing Watch now Build great games for spatial computing Watch now

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  Human Interface Guidelines

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  Design for visionOS

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  “We’re trying to drive change": Meet three App Store Award-winning teams

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    Every year, the App Store Awards celebrate exceptional apps that improve people’s lives while showcasing the highest levels of technical innovation, user experience, design, and positive cultural impact.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    This year’s winners were drawn from a list of 40 finalists that included everything from flight trackers to retro games to workout planners to meditative puzzles. In addition to exhibiting an incredible variety of approaches, styles, and techniques, these winners shared a thoughtful grasp and mastery of Apple tools and technologies.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    Meet the winners and finalists of the 2023 App Store Awards

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    For the team behind the hidden-object game Finding Hannah, their win for Cultural Impact is especially meaningful. “We’re trying to drive change on the design level by bringing more personal stories to a mainstream audience,” says Franziska Zeiner, cofounder and managing director of the Fein Games studio, from her Berlin office. “Finding Hannah is a story that crosses three generations, and each faces the question: How truly free are we as women?”

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    Finding Hannah’s story is driven by quiet, meaningful interactions between the main character, her mother, and her grandmother.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    The Hannah of Finding Hannah is a 39-year-old Berlin resident trying to navigate a career, relationships (including with her best friend/ex, Emma), and the meaning of true happiness. Players complete a series of found-object puzzles that move along the backstory of Hannah’s mother and grandmother to add a more personal touch to the game.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    We’re trying to drive change on the design level by bringing more personal stories to a mainstream audience.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    Franziska Zeiner, Fein Games co-founder and managing director

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    To design the art for the game’s different time periods, the team tried a different approach. “We wanted an art style that was something you’d see more on social media than in games,” says Zeiner. “The idea was to try to reach people who weren’t gamers yet, and we thought we’d most likely be able to do that if we found a style that hadn’t been seen in games before. And I do think that added a new perspective, and maybe helped us stand out a little bit.”

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    Learn more about Finding Hannah

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    Download Finding Hannah from the App Store

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    Pixelmator, the team behind Mac App of the Year winner Photomator, is no stranger to awards consideration, having received multiple Apple Design Awards in addition to their 2023 App Store Award. The latter is especially meaningful for the Lithuania-based team. “We’re still a Mac-first company,” says Simonas Bastys, lead developer of the Pixelmator team. “For what we do, Mac adds so many benefits to the user experience.”

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    Photomator’s Smart Deband feature is just one of its many powerful features on Mac.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    To start adding Photomator to their portfolio of Mac apps back in 2020, Bastys and his team of engineers decided against porting over their UIKit and AppKit code. Instead, they set out to build Photomator specifically for Mac with SwiftUI. “We had a lot of experience with AppKit,” Bastys says, “but we chose to transition to SwiftUI to align with cutting-edge, future-proof technologies.”

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    The team zeroed in on maximizing performance, assuming that people would need to navigate and manipulate large libraries. They also integrated a wealth of powerful editing tools, such as repairing, debanding, batch editing, and much more. Deciding what to work on — and what to prioritize — is a constant source of discussion. “We work on a lot of ideas in parallel,” Bastys says, “and what we prioritize comes up very naturally, based on what’s ready for shipment and what new technology might be coming.” This year, that meant a focus on HDR.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    We had a lot of experience with AppKit, but we wanted to create with native Mac technologies.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    Simonas Bastys, lead developer of the Pixelmator team

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    How does Bastys and the Pixelmator team keep growing after so long? “This is the most exciting field in computer science to me,” says Bastys. “There’s so much to learn. I’m only now starting to even understand the depth of human vision and computer image processing. It’s a continuous challenge. But I see endless possibilities to make Photomator better for creators.”

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    Learn more about Photomator

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    Download Photomator from the Mac App Store

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    To create the Cultural Impact winner Unpacking, the Australian duo of creative director Wren Brier and technical director Tim Dawson drew on more than a decade of development experience. Their game — part zen puzzle, part life story — follows a woman through the chapters of her life as she moves from childhood bedroom to first apartment and beyond. Players solve puzzles by placing objects around each new dwelling while learning more about her history with each new level — something Brier says is akin to a detective story.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    “You have this series of places, and you’re opening these hints, and you’re piecing together who this person is,” she says from the pair’s home in Brisbane.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    Brier and Dawson are partners who got the idea for Unpacking from — where else? — one of their own early moves. “There was something gamelike about the idea of finishing one box to unlock the one underneath,” Brier says. “You’re completing tasks, placing items together on shelves and in drawers. Tim and I started to brainstorm the game right away.”

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    Unpacking has no visible characters and no dialogue. Its emotionally rich story is told entirely through objects in boxes.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    While the idea was technically interesting, says Dawson, the pair was especially drawn to the idea of unpacking as a storytelling vehicle. “This is a really weird example,” laughs Dawson, “but there’s a spatula in the game. That’s a pretty normal household item. But what does it look like? Is it cheap plastic, something that maybe this person got quickly? Is it damaged, like they’ve been holding onto it for a while? Is it one of those fancy brands with a rubberized handle? All of that starts painting a picture. It becomes this really intimate way of knowing a character.”

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    There was something game-like about the idea of finishing one box to unlock the one underneath.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    Wren Brier, Unpacking creative director

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    Those kinds of discussions — spatula-based and otherwise — led to a game that includes novel uses of technology, like the haptic feedback you get when you shake a piggy bank or board game. But its diverse, inclusive story is the reason behind its App Store Award nod for Cultural Impact. Brier and Dawson say players of all ages and backgrounds have shared their love of the game, drawn by the universal experience of moving yourself, your belongings, and your life into a new home. “One guy even sent us a picture of his bouldering shoes and told us they were identical to the ones in the game,” laughs Brier. “He said, ‘I have never felt so seen.’”

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    Learn more about Unpacking

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    Download Unpacking from the App Store

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    With Ancient Board Game Collection, Klemens Strasser goes back in time

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      Klemens Strasser will be the first to tell you that prior to launching his Ancient Board Game Collection, he wasn’t especially skilled at Hnefatafl. “Everybody knows chess and everybody knows backgammon,” says the indie developer from his home office in Austria, “but, yeah, I didn’t really know that one.”

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      Today, Strasser runs what may well be the hottest Hnefatafl game in town. The Apple Design Award finalist for Inclusivity Ancient Board Game Collection comprises nine games that reach back not years or decades but centuries — Hnefatafl (or Viking chess) is said to be nearly 1,700 years old, while the Italian game Latrunculi is closer to 2,000. And while games like Konane, Gomoku, and Five Field Kono might not be household names, Strasser’s collection gives them fresh life through splashy visuals, a Renaissance faire soundtrack, efficient onboarding, and even a bit of history.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      At roughly 1,700 years old, Hnefatafl is one of the more ancient titles in Klemens Strasser’s Ancient Board Game Collection.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      Strasser is a veteran of Flexibits (Fantastical, Cardhop) and the developer behind such titles as Letter Rooms, Subwords and Elementary Minute (for which he won a student Apple Design Award in 2015). But while he was familiar with Nine Men’s Morris — a game popular in Austria he’d play with his grandma — he wasn’t exactly well versed in third-century Viking pastimes until a colleague brought Hnefatafl to his attention three years ago. “It was so different than the traditional symmetric board games I knew,” he says. “I really fell in love with it.”

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      Less appealing were mobile versions of Hnefatafl, which Strasser found lacking. “The digital versions of many board games have a certain design,” he says. “It’s usually pretty skeuomorphic, with a lot of wood and felt and stuff like that. That just didn’t make me happy. And I thought, ‘Well, if I can’t find one I like, I’ll build it.’”

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      I found a book on ancient board games by an Oxford professor and it threw me right down a rabbit hole.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      Klemens Strasser

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      Using SpriteKit, Strasser began mocking up an iOS Hnefatafl prototype in his downtime. A programmer by trade — “I’m not very good at drawing stuff,” he demurs — Strasser took pains to keep his side project as simple as possible. “I always start with minimalistic designs for my games and apps, but these are games you play with some stones and maybe a piece of paper,” he laughs. “I figured I could build that myself.”

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      His Hnefatafl explorations came surprisingly fast — enough so that he started wondering what other long-lost games might be out there. “I found a book on ancient board games by an Oxford professor and it threw me right down a rabbit hole,” Strasser laughs. “I kept saying, ‘Oh, that’s an interesting game, and that’s also an interesting game, and that’s another interesting game.’” Before he knew it, his simple Hnefatafl mockup had become a buffet of games. “And I still have a list of like 20 games I’d still like to digitize,” he says.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      Italian designer Carmine Acierno brought a mosaic-inspired design to Nine Men’s Morris.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      For the initial designs of his first few games, Strasser tried to maintain the simple style of his Hnefatafl prototype. “But I realized that I couldn’t really represent the culture and history behind each game in that way,” he says, “so I hired people who live where the games are from.”

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      That’s where Ancient Board Game Collection really took off. Strasser began reaching out to artists from each ancient game’s home region — and the responses came fast. Out went the minimalist version of Ancient Board Game Collection, in came a richer take, powered by a variety of cultures and design styles. For Hnefatafl, Strasser made a fortuitous connection with Swedish designer Albina Lind. “I sent her a few images of like Vikings and runestones, and in two hours she came up with a design that was better than anything I could have imagined,” he says. “If I hadn’t run into her, I might not have finished the project. But it was so perfect that I had to continue.”

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      Stockholm-based artist Albina Lind leapt right into designing Hnefatafl. “I instantly thought, ‘Well, this is my cup of tea,’” she says.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      Lind was a wise choice. The Stockholm-based freelance artist had nearly a decade of experience designing games, including her own Norse-themed adventure, Dragonberg. “I instantly thought, ‘Well, this is my cup of tea,’” Lind says. Her first concept was relatively realistic, all dark wood and stone textures, before she settled on a more relaxed, animation-inspired style. “Sometimes going unreal, going cartoony, is even more work than being realistic,” she says with a laugh. Lind went on to design two additional ancient games: Dablot, the exact origins of which aren’t known but it which first turned up in 1892, and Halatafl, a 14th century game of Scandinavian origin.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      Work arrived from around the globe. Italian designer Carmine Acierno contributed a mosaic-inspired version of Nine Men’s Morris; Honolulu-based designer Anna Fujishige brought a traditional Hawaiian flavor to Konane. And while the approach succeeded in preserving more of each game’s authentic heritage, it did mean iterating with numerous people over numerous emails. One example: Tokyo-based designer Yosuke Ando pitched changing Strasser’s initial designs for the Japanese game Gomoku altogether. “Klemens approached me initially with the idea of the game design to be inspired by ukiyo-e (paintings) and musha-e (woodblocks prints of warriors),” Ando says. “Eventually, we decided to focus on samurai warrior armor from musha-e, deconstructing it, and simplifying these elements into the game UI.”

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      Honolulu-based designer Anna Fujishige brought a traditional Hawaiian flavor to Konane (at left), while the Tokyo designer Yosuke Ando’s ideas for Gomoku were inspired by samurai warrior armor.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      While the design process continued, Strasser worked on an onboarding strategy — times nine. As you might suspect, it can be tricky to explain the rules and subtleties of 500-year-old games from lost civilizations, and Strasser’s initial approach — walkthroughs and puzzles designed to teach each game step by step — quickly proved unwieldy. So he went in the other direction, concentrating on writing “very simple, very understandable” rules with short gameplay animations that can be accessed at any time. “I picked games that could be explained in like three or four sentences,” he says. “And I wanted to make sure it was all accessible via VoiceOver.”

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      Strasser designed every part of Ancient Board Game Collection with accessibility in mind.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      In fact, accessibility remained a priority throughout the entire project. (He wrote his master’s thesis on accessibility in Unity games.) As an Apple Design Award finalist for Inclusivity, Ancient Board Game Collection shines with best-in-class VoiceOver adoption, as well as support for Reduce Motion, Dynamic Type, and high-contrast game boards. “It’s at least some contribution to making everything better for everyone,” he says.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      I picked games that could be explained in like three or four sentences. And I wanted to make sure it was all accessible via VoiceOver.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      Klemens Strasser

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      Ancient Board Game Collection truly is for everyone, and it’s hardly hyperbole to call it a novel way to introduce games like Hnefatafl to a whole new generation of players. “Most people,” he says, “are just surprised that they’ve never heard of these games.”

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      Learn more about Ancient Board Game Collection

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      Download Ancient Board Game Collection from the App Store

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      Behind the Design is a series that explores design practices and philosophies from each of the winners and finalists of the Apple Design Awards. In each story, we go behind the screens with the developers and designers of these award-winning apps and games to discover how they brought their remarkable creations to life.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      Explore more of the 2023 Behind the Design series

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      25 hours of Xcode Cloud now included with the Apple Developer Program

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        Xcode Cloud, the continuous integration and delivery service built into Xcode, accelerates the development and delivery of high-quality apps. It brings together cloud-based tools that help you build apps, run automated tests in parallel, deliver apps to testers, and view and manage user feedback.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        We’re pleased to announce that as of January 2024, all Apple Developer Program memberships will include 25 compute hours per month on Xcode Cloud as a standard, with no additional cost. If you’re already subscribed to Xcode Cloud for free, no additional action is required on your part. And if you haven’t tried Xcode Cloud yet, now is the perfect time to start building your app for free in just a few minutes.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        Learn more about Xcode Cloud

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        Privacy updates for App Store submissions

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          Third-party SDK privacy manifest and signatures. Third-party software development kits (SDKs) can provide great functionality for apps; they can also have the potential to impact user privacy in ways that aren’t obvious to developers and users. As a reminder, when you use a third-party SDK with your app, you are responsible for all the code the SDK includes in your app, and need to be aware of its data collection and use practices.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          At WWDC23, we introduced new privacy manifests and signatures for SDKs to help app developers better understand how third-party SDKs use data, secure software dependencies, and provide additional privacy protection for users. Starting in spring 2024, if your new app or app update submission adds a third-party SDK that is commonly used in apps on the App Store, you’ll need to include the privacy manifest for the SDK. Signatures are also required when the SDK is used as a binary dependency. This functionality is a step forward for all apps, and we encourage all SDKs to adopt it to better support the apps that depend on them.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          Learn more and view list of commonly-used third-party SDKs

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          New use cases for APIs that require reasons. When you upload a new app or app update to App Store Connect that uses an API (including from third-party SDKs) that requires a reason, you’ll receive a notice if you haven’t provided an approved reason in your app’s privacy manifest. Based on the feedback we received from developers, the list of approved reasons has been expanded to include additional use cases. If you have a use case that directly benefits users that isn’t covered by an existing approved reason, submit a request for a new reason to be added.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          Starting in spring 2024, in order to upload your new app or app update to App Store Connect, you’ll be required to include an approved reason in the app’s privacy manifest which accurately reflects how your app uses the API.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          Learn more and view list of APIs and approved reasons

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          New design and technology consultations now available

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            Have questions on designing your app or implementing a technology? We’re here to help you find answers, no matter where you are in your development journey. One-on-one consultations with Apple experts in December — and newly published dates in January — are available now.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            We’ll have lots more consultations and other activities in store for 2024 — online, in person, and in multiple languages.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            Browse the schedule

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            Get your apps ready for the holidays

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              The busiest season on the App Store is almost here! Make sure your apps and games are up to date and ready in advance of the upcoming holidays. We’ll remain open throughout the season and look forward to accepting your submissions. On average, 90% of submissions are reviewed in less than 24 hours. However, reviews may take a bit longer to complete from December 22 to 27.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              Learn about submitting apps

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              App Store Award winners announced

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                Join us in celebrating the work of these outstanding developers from around the world!

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                Discover the winners

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                App Store Award finalists announced

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  Every year, the App Store celebrates exceptional apps that improve people’s lives while showcasing the highest levels of technical innovation, user experience, design, and positive cultural impact. This year we’re proud to recognize nearly 40 outstanding finalists. Winners will be announced in the coming weeks.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  Learn about the finalists

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  PTC is uniting the makers

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    APPLE VISION PRO APPS FOR ENTERPRISE

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    PTC’s CAD products have been at the forefront of the engineering industry for more than three decades. And the company’s AR/VR CTO, Stephen Prideaux-Ghee, has too. “I’ve been doing VR for 30 years, and I’ve never had this kind of experience before,” he says. “I almost get so blasé about VR. But when I had [Apple Vision Pro] on, walking around digital objects and interacting with others in real time — it’s one of those things that makes you stop in your tracks."

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    Prideaux-Ghee says Apple Vision Pro offers PTC an opportunity to bring together components of the engineering and manufacturing process like never before. “Our customers either make stuff, or they make the machines that help somebody else make stuff,” says Prideaux-Ghee. And that stuff can be anything from chairs to boats to spaceships. “I can almost guarantee that the chair you’re sitting on is made by one of our customers,” he says.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    As AR/VR CTO (which he says means “a fancy title for somebody who comes up with crazy ideas and has a reasonably good chance of implementing them”), Prideaux-Ghee describes PTC’s role as the connective tissue between the multiple threads of production. “When you’ve got a big, international production process, it's not always easy for the people involved to talk to each other. Our thought was: ‘Hey, we’re in the middle of this, so let’s come up with a simple mechanism that allows everyone to do so.’”

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    I’ve been doing VR for 30 years, and I’ve never had this kind of experience before.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    Stephen Prideaux-Ghee, AR/VR CTO of PTC

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    For PTC, it’s all about communication and collaboration. “You can be a single user and get a lot of value from our app,” says Prideaux-Ghee, “but it really starts when you have multiple people collaborating, either in the same room or over FaceTime and SharePlay.” He speaks from experience; PTC has tested its app with everyone in the same space, and spread out across different countries.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    "It enables some really interesting use cases, especially with passthrough," says Prideaux-Ghee. "You can use natural human interactions with a remote device."

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    Development is going fast. In recent weeks, PTC completed a prototype in which changes made on their iPad CAD software immediately reflect in Apple Vision Pro. “Before, we weren’t able to drive from the CAD software,” he explains. “Now, one person can run our CAD software pretty much unmodified and another can see changes instantly in 3D, at full scale. It’s really quite magical.”

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    Read more

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    Businesses of all kinds and sizes are exploring the possibilities of the infinite canvas of Apple Vision Pro — and realizing ideas that were never before possible.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    JigSpace is in the driver’s seat View now

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    Optimize your game for Apple platforms

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      In this series of videos, you can learn how to level up your pro app or game by harnessing the speed and power of Apple platforms. We’ll discover GPU advancements, explore new Metal profiling tools for M3 and A17 Pro, and share performance best practices for Metal shaders.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      Explore GPU advancements in M3 and A17 Pro Watch now Discover new Metal profiling tools for M3 and A17 Pro Watch now Learn performance best practices for Metal shaders Watch now

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      New to developing games for Apple platforms? Familiarize yourself with the tools and technologies you need to get started.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      JigSpace is in the driver’s seat

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        APPLE VISION PRO APPS FOR ENTERPRISE

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        It’s one of the most memorable images from JigSpace’s early Apple Vision Pro explorations: A life-size Alfa Romeo C43 Formula 1 car, dark cherry red, built to scale, reflecting light from all around, and parked right in the room. The camera pans back over the car’s front wings; a graceful animation shows airflow over the wings and body.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        Numa Bertron, cofounder and chief technology officer for JigSpace — the creative and collaborative company that partnered with Alfa Romeo for the model — has been in the driver’s seat for the project from day one and still wasn’t quite prepared to see the car in the spatial environment. “The first thing everyone wanted to do was get in,” he says. “Everyone was stepping over the side to get in, even though you can just, you know, walk through.”

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        The F1 car is just one component of JigSpace’s grand plans for visionOS. The company is leaning on the new platform to create avenues of creativity and collaboration never before possible.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        Bertron brings up one of JigSpace’s most notable “Jigs” (the company term for spatial presentations): an incredibly detailed model of a jet engine. “On iPhone, it’s an AR model that expands and looks awesome, but it’s still on a screen,” he explains. On Apple Vision Pro, that engine becomes a life-size piece of roaring, spinning machinery — one that people can walk around, poke through, and explore in previously unimaginable detail.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        “One of our guys is a senior 3D artist,” says Bertron, “and the first time he saw one of his models in space at scale — and walked around it with his hands free — he actually cried.”

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        We made that F1 Jig with tools everyone can use.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        Numa Bertron, JigSpace cofounder and chief technology officer

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        Getting there required some background learning. Prior to developing for visionOS, Bertron had no experience with SwiftUI. “We’d never gone into Xcode, so we started learning SwiftUI and RealityKit. Honestly, we expected some pain. But since everything is preset, we had really nice rounded corners, blur effects, and smooth scrolling right off the bat.”

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        JigSpace is designing a “full-on collaboration platform,” says Bertron.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        For people who’ve used JigSpace on iOS, the visionOS version will look familiar but feel quite different. “We asked ourselves: What's the appropriate size for an object in front of you?” asks Bertron. “What’s comfortable? Will that model be on the table or on the floor? Spatial computing introduces so many more opportunities — and more decisions.”

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        In the case of the F1 example, it also offers a chance to level up visually. “For objects that big, we’d never been able to achieve this level of fidelity on smaller devices, so we always had to compromise,” says Bertron. In visionOS, they were free to keep adding. “We’d look at a prototype and say, ‘Well, this still runs, so let’s double the size of the textures and add more screws and more effects!’” (It’s not just about functionality, but fun as well. You can remove a piece of the car — like a full-sized tire — and throw it backwards over your head.)

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        The incredible visual achievement is matched by new powers of collaboration. “If I point at the tire, the other person sees me, no matter where they are,” says Bertron. “I can grab the wheel and give it to them. I can circle something we need to fix, I can leave notes or record audio. It’s a full-on collaboration platform.” And it’s also for everyone, not just F1 drivers and aerospace engineers. “We made that F1 Jig with tools everyone can use.”

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        Download JigSpace from the App Store

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        Read more

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        Businesses of all kinds and sizes are exploring the possibilities of the infinite canvas of Apple Vision Pro — and realizing ideas that were never before possible.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        PTC is uniting the makers View now

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        The “sweet, creative” world of Kimono Cats

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          Games simply don’t get much cuter than Kimono Cats, a casual cartoon adventure about two cats on a date (awww) that creator Greg Johnson made as a present for his wife. “I wanted to make a game she and I could play together,” says the Maui-based indie developer, “and I wanted it to be sweet, creative, and romantic.”

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          Kimono Cats is all three, and it’s also spectacularly easy to play and navigate. This Apple Design Award finalist for Interaction in games is set in a Japanese festival full of charming mini-games — darts, fishing, and the like — that are designed for maximum simplicity and casual fun. Players swipe up to throw darts at balloons that contain activities, rewards, and sometimes setbacks that threaten to briefly derail the date. Interaction gestures (like scooping fish) are simple and rewarding, and the gameplay variation and side activities (like building a village for your feline duo) fit right in.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          “I wanted something sweet, creative, and romantic,” says Kimono Cats developer Greg Johnson.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          “I’m a huge fan of Hayao Miyazaki and that kind of heartfelt, slower-paced style,” says Johnson. “What you see in Kimono Cats is a warmth and appreciation for Japanese culture.”

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          You also see a game that’s a product of its environment. Johnson’s been creating games since 1983 and is responsible for titles like Starfight, ToeJam and Earl, Doki-Doki Universe, and many more. His wife, Sirena, is a builder of model houses — miniature worlds not unlike the village in Kimono Cats. And the game’s concept was a reaction to the early days of COVID-19 lockdowns. “When we started building this in 2020, everybody was under so much weight and pressure,” he says. “We felt like this was a good antidote.”

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          Early Kimono Cats sketches show how the characters’ cute look was established early in the design process.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          To start creating the game, Johnson turned to artist and longtime collaborator Ferry Halim, as well as Tanta Vorawatanakul and Ferrari Duanghathai, a pair of developers who happen to be married. “Tanta and Ferrari would provide these charming little characters, and Ferry would come in to add animations — like moving their eyes,” says Johnson. “We iterated a lot on animating the bubbles — how fast they were moving, how many there were, how they were obscured. That was the product of a lot of testing and listening all throughout the development process.”

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          When we started with this in 2020, everybody was under so much weight and pressure. We felt like this was a good antidote.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          Greg Johnson, Kimono Cats

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          Johnson notes that players can select characters without gender distinction — a detail that he and the Kimono Cats team prioritized from day one. “Whenever any companion kisses the player character on the cheek, a subtle rainbow will appear in the sky over their heads,” Johnson says. “This allows the gender of the cat characters to be open to interpretation by the users.”

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          Kimono Cats was designed with the simple goal of bringing smiles. “The core concept of throwing darts at bubbles isn't an earth-shaking idea by any stretch,” says Johnson, “but it was a way to interact with the storytelling that I hadn’t seen before, and the festival setting felt like a natural match.”

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          Learn more about Kimono Cats

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          Find Kimono Cats on Apple Arcade

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          Behind the Design is a series that explores design practices and philosophies from each of the winners and finalists of the Apple Design Awards. In each story, we go behind the screens with the developers and designers of these award-winning apps and games to discover how they brought their remarkable creations to life.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          Explore more of the 2023 Behind the Design series

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          Spotlight on: Apple Vision Pro apps for enterprise

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            Businesses of all kinds and sizes are exploring the possibilities of the infinite canvas of Apple Vision Pro — and realizing ideas that were never before possible. We caught up with two of those companies — JigSpace and PTC — to find out how they’re approaching the new world of visionOS.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            JigSpace is in the driver’s seat View now PTC is uniting the makers View now

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            Reimagine your enterprise apps on Apple Vision Pro

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              Discover the languages, tools, and frameworks you’ll need to build and test your apps in visionOS. Explore videos and resources that showcase productivity and collaboration, simulation and training, and guided work. And dive into workflows for creating or converting existing media, incorporating on-device and remote assets into your app, and much more.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              Apple Vision Pro at work Keynote Watch now Keynote (ASL) Watch now Platforms State of the Union Watch now Platforms State of the Union (ASL) Watch now Design for Apple Vision Pro

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              WWDC sessions

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              Design for spatial input Watch now Design for spatial user interfaces Watch now Principles of spatial design Watch now Design considerations for vision and motion Watch now Explore immersive sound design Watch now

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              Sample code, articles, documentation, and resources

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              Destination Video

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              Diorama

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              Hello World

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              Happy Beam

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              Apple Design Resources

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              Design for visionOS

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              Developer paths to Apple Vision Pro

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              WWDC sessions

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              Go beyond the window with SwiftUI Watch now Meet SwiftUI for spatial computing Watch now Meet ARKit for spatial computing Watch now What’s new in SwiftUI Watch now Discover Observation in SwiftUI Watch now Enhance your spatial computing app with RealityKit Watch now Build spatial experiences with RealityKit Watch now Evolve your ARKit app for spatial experiences Watch now Create immersive Unity apps Watch now Bring your Unity VR app to a fully immersive space Watch now Meet Safari for spatial computing Watch now Rediscover Safari developer features Watch now Design for spatial input Watch now Explore the USD ecosystem Watch now Explore USD tools and rendering Watch now

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              Sample code, articles, documentation, and resources

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              Unity – Unity for visionOS

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              Unity – XR Interaction Toolkit package

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              Unity – How Unity builds applications for Apple platforms

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              three.js – webGL and WebXR library

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              babylon.js – webGL and WebXR library

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              PlayCanvas – webGL and WebXR library

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              w3.org – Model element

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              AOUSD – Alliance for OpenUSD

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              Immersiveweb – WebXR Device API

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              WebKit.org – Bug tracking for WebKit open source project

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              A-Frame WebXR framework

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              Frameworks to explore

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              WWDC sessions

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              Discover streamlined location updates Watch now Meet MapKit for SwiftUI Watch now What's new in MapKit Watch now Build spatial SharePlay experiences Watch now Share files with SharePlay Watch now Design spatial SharePlay experiences Watch now Discover Quick Look for spatial computing Watch now Create 3D models for Quick Look spatial experiences Watch now Explore pie charts and interactivity in Swift Charts Watch now Elevate your windowed app for spatial computing Watch now Create a great spatial playback experience Watch now Deliver video content for spatial experiences Watch now

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              Sample code, articles, documentation, and resources

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              Placing content on detected planes

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              Incorporating real-world surroundings in an immersive experience

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              Tracking specific points in world space

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              Tracking preregistered images in 3D space

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              Explore a location with a highly detailed map and Look Around

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              Drawing content in a group session

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              Supporting Coordinated Media Playback

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              QuickLook example files

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              Visualizing your app’s data

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              Adopting live updates in Core Location

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              Monitoring location changes with Core Location

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              Access enterprise data and assets

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              WWDC sessions

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              Meet Swift OpenAPI Generator Watch now Advances in Networking, Part 1 Watch now Advances in App Background Execution Watch now The Push Notifications primer Watch now Power down: Improve battery consumption Watch now Build robust and resumable file transfers Watch now Efficiency awaits: Background tasks in SwiftUI Watch now Use async/await with URLSession Watch now Meet SwiftData Watch now Explore the USD ecosystem Watch now What’s new in App Store server APIs Watch now

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              Sample code, articles, documentation, and resources

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              grpc-swift

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              swift-protobuf

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              Announcing the Swift Student Challenge 2024

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                Apple is proud to support and uplift the next generation of student developers, creators, and entrepreneurs. The Swift Student Challenge has given thousands of students the opportunity to showcase their creativity and coding capabilities through app playgrounds, and build real-world skills that they can take into their careers and beyond. From connecting their peers to mental health resources to identifying ways to support sustainability efforts on campus, Swift Student Challenge participants use their creativity to develop apps that solve problems they’re passionate about.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                We’re releasing new coding resources, working with community partners, and announcing the Challenge earlier than in previous years so students can dive deep into Swift and the development process — and educators can get a head start in supporting them.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                Applications will open in February 2024 for three weeks.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                New for 2024, out of 350 overall winners, we’ll recognize 50 Distinguished Winners for their outstanding submissions and invite them to join us at Apple in Cupertino for three incredible days next summer.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                Learn more

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                Over 30 new developer activities now available

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  Ready to level up your app or game? Join us around the world for a new set of developer labs, consultations, sessions, and workshops, hosted in person and online throughout November and December.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  You can explore:

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  Discover activities in multiple time zones and languages.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  Browse the full schedule

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  Tax updates for apps, in-app purchases, and subscriptions

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    The App Store’s commerce and payments system was built to enable you to conveniently set up and sell your products and services on a global scale in 44 currencies across 175 storefronts. Apple administers tax on behalf of developers in over 70 countries and regions and provides you with the ability to assign tax categories to your apps and in‑app purchases.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    Periodically, we make updates to rates, categories, and agreements to accommodate new regulations and rate changes in certain regions. As of today, the following updates have been made in App Store Connect.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    Tax rates

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    Your proceeds from the sale of eligible apps and in‑app purchases (including auto‑renewable subscriptions) have been increased to reflect the following reduced value-added tax (VAT) rates. Prices on the App Store haven’t changed.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    • Austria: Reduced VAT rates for certain apps in the Video tax category
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    • Cyprus: Reduced VAT rate of 3% for certain apps in the following tax categories: Books, News Publications, Audiobooks, Magazines and other periodicals
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    • Vietnam: Eliminated VAT for certain apps in the following tax categories: Books, News Publications, Magazines, and other periodicals
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    Tax categories
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    • New Boosting category: Apps and/or in-app purchases that offer resources to provide exposure, visibility, or engagement to enhance the prominence and reach of specific content that’s experienced or consumed in app (such as videos, sales of “boosts” in social media apps, listings, and/or other forms of user-generated content).
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    • New attribute for books: Textbook or other educational publication used for teaching and studying between ages 5 to 18
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    • New attributes for videos: Exclusively features live TV broadcasting and/or linear programming. Public TV broadcasting, excluding shopping or infomercial channels.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    If any of these categories or attributes are relevant to your apps or in-app purchases, you can review and update your selections in the Pricing and Availability section of My Apps.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    Learn about setting tax categories

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    Paid Applications Agreement
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    • Exhibit C Section 1.2.2: Updated language to clarify the goods and services tax (GST) requirements for developers on the Australia storefront.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    Get ready with the latest beta releases

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      The beta versions of iOS 17.2, iPadOS 17.2, macOS 14.2, tvOS 17.2, and watchOS 10.2 are now available. Get your apps ready by confirming they work as expected on these releases. And to take advantage of the advancements in the latest SDKs, make sure to build and test with Xcode 15.1 beta.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      To check if a known issue from a previous beta release has been resolved or if there’s a workaround, review the latest release notes. Please let us know if you encounter an issue or have other comments. We value your feedback, as it helps us address issues, refine features, and update documentation.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      View downloads and release notes

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      Learn about testing a beta OS

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      Learn about sending feedback

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      TestFlight makes it even simpler to manage testers

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        TestFlight provides an easy way to get feedback on beta versions of your apps, so you can publish on the App Store with confidence. Now, improved controls in App Store Connect let you better evaluate tester engagement and manage participation to help you get the most out of beta testing. Sort testers by status and engagement metrics (like sessions, crashes, and feedback), and remove inactive testers who haven’t engaged. You can also filter by device and OS, and even select relevant testers to add to a new group.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        Learn about managing testers

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        Learn about TestFlight

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        Scary fast.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          Watch the October 30 event at apple.com.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          New delivery metrics now available in the Push Notifications Console

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            The Push Notifications Console now includes metrics for notifications sent in production through the Apple Push Notification service (APNs). With the console’s intuitive interface, you’ll get an aggregated view of delivery statuses and insights into various statistics for notifications, including a detailed breakdown based on push type and priority.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            Introduced at WWDC23, the Push Notifications Console makes it easy to send test notifications to Apple devices through APNs.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            Learn more

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            Apple Vision Pro developer labs expand to New York City and Sydney

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              We’re thrilled with the excitement and enthusiasm from developers around the world at the Apple Vision Pro developer labs, and we’re pleased to announce new labs in New York City and Sydney. Join us to test directly on the device and connect with Apple experts for help with taking your visionOS, iPadOS, and iOS apps even further on this exciting new platform. Labs also take place in Cupertino, London, Munich, Shanghai, Singapore, and Tokyo.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              Submit a lab request

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              Learn about other ways to work with Apple to prepare for visionOS.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              “Small but mighty”: How Plex serves its global community

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                The team behind Plex has a brilliant strategy for dealing with bugs and addressing potential issues: Find them first.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                “We’ve got a pretty good process in place,” says Steve Barnegren, Plex senior software engineer on Apple platforms, “and when that’s the case, things don’t go wrong.”

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                Launched in 2009, Plex is designed to serve as a “global community for streaming content,” says engineering manager Alex Stevenson-Price, who’s been with Plex for more than seven years. A combination streaming service and media server, Plex aims to cover the full range of the streaming experience — everything from discovery to content management to organizing watchlists.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                This allows us more time to investigate the right solutions.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                Ami Bakhai, Plex product manager for platforms and partners

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                To make it all run smoothly, the Plex team operates on a six-week sprint, offering regular opportunities to think in blocks, define stop points in their workflow, and assess what’s next. “I’ve noticed that it provides more momentum when it comes to finalizing features or moving something forward,” says Ami Bakhai, product manager for platforms and partners. “Every team has their own commitments. This allows us more time to investigate the right solutions.”

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                The Plex team iterates, distributes, and releases quickly — so testing features and catching issues can be a tall order. (Plex releases regular updates during their sprints for its tvOS flagship, iOS, iPadOS, and macOS apps.)

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                Though Plex boasts a massive reach across all the platforms, it’s not powered by a massive number of people. The fully remote team relies on a well-honed mix of developer tools (like Xcode Cloud and TestFlight), clever internal organization, Slack integration, and a thriving community of loyal beta testers that stretches back more than a decade. “We’re relatively small,” says Danni Hemberger, Plex director of product marketing, “but we’re mighty.”

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                Over the summer, the Plex team made a major change to their QA process: Rather than bringing in their QA teams right before the release, they shifted QA to a continuous process that unfolds over every pull request. “The QA team would find something right at the end, which is when they’d start trying to break everything,” laughs Barnegren. “Now we can say, ‘OK, ten features have gone in, and all of them have had QA eyes on them, so we’re ready to press the button.’”

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                Now we can say, ‘OK, ten features have gone in, and all of them have had QA eyes on them, so we’re ready to press the button.'

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                Steve Barnegren, Plex senior software engineer on Apple platforms

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                The continuous QA process is a convenient mirror to the continuous delivery process. Previously, Plex tested before a new build was released to the public. Now, through Xcode Cloud, Plex sends nightly builds to all their employees, ensuring that everyone has access to the latest version of the app.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                Once the release has been hammered out internally, it moves on to Plex’s beta testing community, which might be more accurately described as a beta testing city. It numbers about 8,000 people, some of whom date back to Plex’s earliest days. “That constant feedback loop is super valuable, especially when you have power users that understand your core product,” says Stevenson-Price.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                All this feedback and communication is powered by TestFlight and Plex’s customer forums. “This is especially key because we have users supplying personal media for parts of the application, and that can be in all kinds of rare or esoteric formats,” says Barnegren.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                [CI] is a safety net. Whenever you push code, your app is being tested and built in a consistent way. That’s so valuable, especially for a multi-platform app like ours.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                Alex Stevenson-Price, Plex engineering manager

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                To top it all off, this entire process is automated with every new feature and every new bug fix. Without any extra work or manual delivery, the Plex team can jump right on the latest version — an especially handy feature for a company that’s dispersed all over the globe. “It’s a great reminder of ‘Hey, this is what’s going out,’ and allows my marketing team to stay in the loop,” says Hemberger.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                It’s also a great use of a continuous integration system (CI). “I’m biased from my time spent as an indie dev, but I think all indie devs should try a CI like Xcode Cloud,” says Stevenson-Price. “I think some indies don’t always see the benefit on paper, and they’ll say, ‘Well, I build the app myself, so why do I need a CI to build it for me?’ But it’s a safety net. Whenever you push code, your app is being tested and built in a consistent way. That’s so valuable, especially for a multi-platform app like ours. And there are so many tools at your disposal. Once you get used to that, you can’t go back.”

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                Learn more about Plex

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                Download Plex from the App Store

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                The gorgeous gadgets of Automatoys

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  Steffan Glynn’s Automatoys is a mix between a Rube Goldberg machine and a boardwalk arcade game — and there’s a very good reason why.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  In 2018, the Cardiff-based developer visited the Musée Mécanique, a vintage San Francisco arcade packed with old-timey games, pinball machines, fortune tellers, and assorted gizmos. On that same trip, he stopped by an exhibit of Rube Goldberg sketches that showcased page after page of wildly intricate machines. “It was all about the delight of the pointless and captivating,” Glynn says. “There was a lot of crazy inspiration on that trip.”

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  An early sketch of the ramps, mazes, and machines that combine to create the puzzles in Automatoys.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  That inspiration turned into Automatoys, an Apple Design Award finalist for Interaction in games. Automatoys is a single-touch puzzler in which players roll their marble from point A to point B by navigating a maze of ramps, elevators, catapults, switches, and more. True to its roots, the game is incredibly tactile; every switch and button feels lifelike, and players even insert a virtual coin to launch each level. And it unfolds to a relaxing and jazzy lo-fi soundtrack. “My brief to the sound designer was, ‘Please make this game less annoying,’” Glynn laughs.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  While Automatoys’ machines may be intricate, its controls are anything but. Every button, claw, and catapult is controlled by a single tap. “And it doesn’t matter where you tap — the whole machine moves at once,” Glynn says. The mechanic doesn’t just make the game remarkably simple to learn; it also creates a sense of discovery. “I like that moment when the player is left thinking, ‘OK, well, I guess I’ll just start tapping and find out what happens.’”

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  To create levels in Automatoys, Steffan Glynn worked directly in the 3D space, starting with a basic model (top left) and creating obstacles until he reached a finished whole (bottom right).

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  To design each of the game’s 12 levels, Glynn first sketched his complex contraptions in Procreate. The ideas came fast and furious, but he found that building what he’d envisioned in his sketches proved elusive — so he changed his strategy. “I started playing with shapes directly in 3D space,” he says. “Once a level had a satisfying form, I’d then try to imagine what sort of obstacle each part could be. One cylinder would become a ferris wheel, another would become a spinning helix for the ball to climb, a square panel would become a maze, and so on.”

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  Getting your marble from point A to point B is as simple as this.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  The game was a four-year passion project for Glynn, a seasoned designer who in 2018 left his gig with State of Play (where he contributed to such titles as Lumino City and Apple Design Award winner INKS.) to focus on creating “short, bespoke” games. There was just one catch: Though he had years of design experience, he’d never written a single line of code. To get up to speed, he threw himself into video tutorials and hands-on practice.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  Welsh developer Steffan Glynn set out on his own in 2018 to create “short, bespoke” games.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  In short order, Glynn was creating Unity prototypes of what would become Automatoys. “As a designer, being able to prototype and test ideas is incredibly liberating. When you have those tools, you can quickly try things out and see for yourself what works.”

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  Learn more about Automatoys

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  Download Automatoys from the App Store

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  Behind the Design is a series that explores design practices and philosophies from each of the winners and finalists of the Apple Design Awards. In each story, we go behind the screens with the developers and designers of these award-winning apps and games to discover how they brought their remarkable creations to life.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  Explore more of the 2023 Behind the Design series

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  Hello Developer: October 2023

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    Find out about our latest activities (including more Apple Vision Pro developer lab dates), learn how the Plex team embraced Xcode Cloud, discover how the inventive puzzle game Automatoys came to life, catch up on the latest news, and more.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    Meet with Apple Experts

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    Hosted in person and online, our developer activities are for everyone, no matter where you are on your development journey. Find out how to enhance your existing app or game, refine your design, or launch a new project. Explore the list of upcoming activities worldwide.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    Get ready for a new round of Apple Vision Pro developer lab dates

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    Developers have been thrilled to experience their apps and games in the labs, and connect with Apple experts to help refine their ideas and answer questions. Ben Guerrette, chief experience officer at Spool, says, “That kind of learning experience is incredibly valuable.” Developer and podcaster David Smith says, “The first time you see your own app running for real is when you get the audible gasp.” Submit a lab request.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    You can also request Apple Vision Pro compatibility evaluations. We’ll evaluate your apps and games directly on Apple Vision Pro to make sure they behave as expected and send you the results.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    “Small but mighty”: Go behind the scenes with Plex

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    Discover how the streaming service and media player uses developer tools like Xcode Cloud to maintain a brisk release pace. “We’re relatively small,” says Danni Hemberger, director of product marketing at Plex, “but we’re mighty.”

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    “Small but mighty”: How Plex serves its global community View now Meet the mind behind Automatoys

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    “I like the idea of a moment where players are left to say, ‘Well, I guess I’ll just start tapping and see what happens,’” says Steffan Glynn of Apple Design Award finalist Automatoys, an inspired puzzler in which players navigate elaborate contraptions with a single tap. Find out how Glynn brought his Rube Goldberg-inspired game to life.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    The gorgeous gadgets of Automatoys View now Catch up on the latest news and updates

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    Make sure you’re up to date on feature announcements, important guidance, new documentation, and more.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    Share your thoughts

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    We’d love to hear from you. If you have suggestions for our activities or stories, please let us know.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    Get ready with the latest beta releases

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      The beta versions of iOS 17.1, iPadOS 17.1, macOS 14.1, tvOS 17.1, and watchOS 10.1 are now available. Get your apps ready by confirming they work as expected on these releases. And to take advantage of the advancements in the latest SDKs, make sure to build and test with Xcode 15.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      To check if a known issue from a previous beta release has been resolved or if there’s a workaround, review the latest release notes. Please let us know if you encounter an issue or have other feedback. We value your feedback, as it helps us address issues, refine features, and update documentation.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      View downloads and release notes

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      Learn about testing a beta OS

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      Learn about sending feedback

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      Meet with Apple Experts

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        Join us around the world for a variety of sessions, consultations, labs, and more — tailored for you.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        Apple developer activities are for everyone, no matter where you are on your development journey. Activities take place all year long, both online and in person around the world. Whether you’re looking to enhance your existing app or game, refine your design, or launch a new project, there’s something for you.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        Learn more

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        Pre-orders by region now available

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          Offering your app or game for pre-order is a great way to build awareness and excitement for your upcoming releases on the App Store. And now you can offer pre-orders on a regional basis. People can pre-order your app in a set of regions that you choose, even while it’s available for download in other regions at the same time. With this new flexibility, you can expand your app to new regions by offering it for pre-order and set different release dates for each region.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          Learn about pre-orders

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          Learn how to manage your app’s availability

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          App Store submissions now open for the latest OS releases

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            iOS 17, iPadOS 17, macOS Sonoma, tvOS 17, and watchOS 10 will soon be available to customers worldwide. Build your apps and games using the Xcode 15 Release Candidate and latest SDKs, test them using TestFlight, and submit them for review to the App Store. You can now start deploying seamlessly to TestFlight and the App Store from Xcode Cloud. With exciting new capabilities, as well as major enhancements across languages, frameworks, tools, and services, you can deliver even more unique experiences on Apple platforms.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            Xcode and Swift. Xcode 15 enables you to code and design your apps faster with enhanced code completion, interactive previews, and live animations. Swift unlocks new kinds of expressive and intuitive APIs by introducing macros. The new SwiftData framework makes it easy to persist data using declarative code. And SwiftUI brings support for creating more sophisticated animations with phases and keyframes, and simplified data flows using the new Observation framework.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            Widgets and Live Activities. Widgets are now interactive and run in new places, like StandBy on iPhone, the Lock Screen on iPad, the desktop on Mac, and the Smart Stack on Apple Watch. With SwiftUI, the system adapts your widget’s color and spacing based on context, extending its usefulness across platforms. Live Activities built with WidgetKit and ActivityKit are now available on iPad to help people stay on top of what’s happening live in your app.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            Metal. The new game porting toolkit makes it easier than ever to bring games to Mac and the Metal shader converter dramatically simplifies the process of converting your game’s shaders and graphics code. Scale your games and production renderers to create even more realistic and detailed scenes with the latest updates to ray tracing. And take advantage of many other enhancements that make it even simpler to deliver fantastic games and pro apps on Apple silicon.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            App Shortcuts. When you adopt App Shortcuts, your app’s key features are now automatically surfaced in Spotlight, letting people quickly access the most important views and actions in your app. A new design makes running your app’s shortcuts even simpler and new natural language capabilities let people execute your shortcuts with their voice with more flexibility.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            App Store. It’s now even simpler to merchandise your in-app purchases and subscriptions across all platforms with new SwiftUI views in StoreKit. You can also test more of your product offerings using the latest enhancements to StoreKit testing in Xcode, the Apple sandbox environment, and TestFlight. With pre-orders by region, you can build customer excitement by offering your app in new regions with different release dates. And with the most dynamic and personalized app discovery experience yet, the App Store helps people find more apps through tailored recommendations based on their interests and preferences.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            And more. Learn about advancements in machine learning, Object Capture, Maps, Passkeys, SharePlay, and so much more.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            Starting in April 2024, apps submitted to the App Store must be built with Xcode 15 and the iOS 17 SDK, tvOS 17 SDK, or watchOS 10 SDK (or later).

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            Download Xcode

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            Learn more about submitting apps

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            Apple Entrepreneur Camp applications now open

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              Apple Entrepreneur Camp supports underrepresented founders and developers, and encourages the pipeline and longevity of these entrepreneurs in technology. Building on the success of our alumni from cohorts for female*, Black, and Hispanic/Latinx founders, starting this fall, we’re expanding our reach to welcome professionals from Indigenous backgrounds who are looking to enhance and grow their existing app-driven businesses. Attendees benefit from one-on-one code-level guidance, receive insight, inspiration, and unprecedented access to Apple engineers and experts, and become part of the extended global network of Apple Entrepreneur Camp alumni.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              Applications are now open for founders and developers from these groups who have either an existing app on the App Store, a functional beta build in TestFlight, or the equivalent. Attendees will join us online starting in October 2023. We welcome eligible entrepreneurs with app-driven organizations to apply and we encourage you to share these details with those who may be interested.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              Apply by September 24, 2023.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              Learn more

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              * Apple believes that gender expression is a fundamental right. We welcome all women to apply to this program.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              Take your iPad and iPhone apps even further on Apple Vision Pro

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                A brand‑new App Store will launch with Apple Vision Pro, featuring apps and games built for visionOS, as well as hundreds of thousands of iPad and iPhone apps that run great on visionOS too. Users can access their favorite iPad and iPhone apps side by side with new visionOS apps on the infinite canvas of Apple Vision Pro, enabling them to be more connected, productive, and entertained than ever before. And since most iPad and iPhone apps run on visionOS as is, your app experiences can easily extend to Apple Vision Pro from day one — with no additional work required.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                Timing. Starting this fall, an upcoming developer beta release of visionOS will include the App Store. By default, your iPad and/or iPhone apps will be published automatically on the App Store on Apple Vision Pro. Most frameworks available in iPadOS and iOS are also included in visionOS, which means nearly all iPad and iPhone apps can run on visionOS, unmodified. Customers will be able to use your apps on visionOS early next year when Apple Vision Pro becomes available.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                Making updates, if needed. In the case that your app requires a capability that is unavailable on Apple Vision Pro, App Store Connect will indicate that your app isn’t compatible and it won’t be made available. To make your app available, you can provide alternative functionality, or update its UIRequiredDeviceCapabilities. If you need to edit your existing app’s availability, you can do so at any time in App Store Connect.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                To see your app in action, use the visionOS simulator in Xcode 15 beta. The simulator lets you interact with and easily test most of your app’s core functionality. To run and test your app on an Apple Vision Pro device, you can submit your app for a compatibility evaluation or sign up for a developer lab.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                Beyond compatibility. If you want to take your app to the next level, you can make your app experience feel more natural on visionOS by building your app with the visionOS SDK. Your app will adopt the standard visionOS system appearance and you can add elements, such as 3D content tuned for eyes and hands input. To learn how to build an entirely new app or game that takes advantage of the unique and immersive capabilities of visionOS, view our design and development resources.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                Watch the special Apple Event

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  Watch the replay from September 12 at apple.com.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  Updated Apple Developer Program License Agreement now available

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    The Apple Developer Program License Agreement has been revised to support upcoming features and updated policies, and to provide clarification. The revisions include:

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    • Definitions, Section 3.3.39: Specified requirements for use of the Journaling Suggestions API.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    • Schedule 1 Exhibit D Section 3 and Schedules 2 and 3 Exhibit E Section 3: Added language about the Digital Services Act (DSA) redress options available to developers based in the European Union.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    • Schedule 1 Section 6.3 and Schedules 2 and 3 Section 7.3: Added clarifying language that the content moderation process is subject to human and systematic review and action pursuant to notices of illegal and harmful content.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    View full terms and conditions

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    Inside the Apple Vision Pro labs

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      As CEO of Flexibits, the team behind successful apps like Fantastical and Cardhop, Michael Simmons has spent more than a decade minding every last facet of his team’s work. But when he brought Fantastical to the Apple Vision Pro labs in Cupertino this summer and experienced it for the first time on the device, he felt something he wasn’t expecting.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      “It was like seeing Fantastical for the first time,” he says. “It felt like I was part of the app.”

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      That sentiment has been echoed by developers around the world. Since debuting in early August, the Apple Vision Pro labs have hosted developers and designers like Simmons in London, Munich, Shanghai, Singapore, Tokyo, and Cupertino. During the day-long lab appointment, people can test their apps, get hands-on experience, and work with Apple experts to get their questions answered. Developers can apply to attend if they have a visionOS app in active development or an existing iPadOS or iOS app they’d like to test on Apple Vision Pro.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      Learn more about Apple Vision Pro developer labs

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      For his part, Simmons saw Fantastical work right out of the box. He describes the labs as “a proving ground” for future explorations and a chance to push software beyond its current bounds. “A bordered screen can be limiting. Sure, you can scroll, or have multiple monitors, but generally speaking, you’re limited to the edges,” he says. “Experiencing spatial computing not only validated the designs we’d been thinking about — it helped us start thinking not just about left to right or up and down, but beyond borders at all.”

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      And as not just CEO but the lead product designer (and the guy who “still comes up with all these crazy ideas”), he came away from the labs with a fresh batch of spatial thoughts. “Can people look at a whole week spatially? Can people compare their current day to the following week? If a day is less busy, can people make that day wider? And then, what if like you have the whole week wrap around you in 360 degrees?” he says. “I could probably — not kidding — talk for two hours about this.”

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      ‘The audible gasp’

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      David Smith is a prolific developer, prominent podcaster, and self-described planner. Shortly before his inaugural visit to the Apple Vision Pro developer labs in London, Smith prepared all the necessary items for his day: a MacBook, Xcode project, and checklist (on paper!) of what he hoped to accomplish.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      All that planning paid off. During his time with Apple Vision Pro, “I checked everything off my list,” Smith says. “From there, I just pretended I was at home developing the next feature.”

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      I just pretended I was at home developing the next feature.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      David Smith, developer and podcaster

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      Smith began working on a version of his app Widgetsmith for spatial computing almost immediately after the release of the visionOS SDK. Though the visionOS simulator provides a solid foundation to help developers test an experience, the labs offer a unique opportunity for a full day of hands-on time with Apple Vision Pro before its public release. “I’d been staring at this thing in the simulator for weeks and getting a general sense of how it works, but that was in a box,” Smith says. “The first time you see your own app running for real, that’s when you get the audible gasp.”

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      Smith wanted to start working on the device as soon as possible, so he could get “the full experience” and begin refining his app. “I could say, ‘Oh, that didn’t work? Why didn’t it work?’ Those are questions you can only truly answer on-device.” Now, he has plenty more plans to make — as evidenced by his paper checklist, which he holds up and flips over, laughing. “It’s on this side now.”

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      ‘We understand where to go’

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      When it came to testing Pixite’s video creator and editor Spool, chief experience officer Ben Guerrette made exploring interactions a priority. “What’s different about our editor is that you’re tapping videos to the beat,” he says. “Spool is great on touchscreens because you have the instrument in front of you, but with Apple Vision Pro you’re looking at the UI you’re selecting — and in our case, that means watching the video while tapping the UI.”

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      The team spent time in the lab exploring different interaction patterns to address this core challenge. “At first, we didn’t know if it would work in our app,” Guerrette says. “But now we understand where to go. That kind of learning experience is incredibly valuable: It gives us the chance to say, ‘OK, now we understand what we’re working with, what the interaction is, and how we can make a stronger connection.’”

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      Chris Delbuck, principal design technologist at Slack, had intended to test the company’s iPadOS version of their app on Apple Vision Pro. As he spent time with the device, however, “it instantly got me thinking about how 3D offerings and visuals could come forward in our experiences,” he says. “I wouldn’t have been able to do that without having the device in hand.”

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      ‘That will help us make better apps’

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      As lab participants like Smith continue their development at home, they’ve brought back lessons and learnings from their time with Apple Vision Pro. “It’s not necessarily that I solved all the problems — but I solved enough to have a sense of the kinds of solutions I’d likely need,” Smith says. “Now there’s a step change in my ability to develop in the simulator, write quality code, and design good user experiences.”

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      I've truly seen how to start building for the boundless canvas.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      Michael Simmons, Flexibits CEO

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      Simmons says that the labs offered not just a playground, but a way to shape and streamline his team’s thinking about what a spatial experience could truly be. “With Apple Vision Pro and spatial computing, I’ve truly seen how to start building for the boundless canvas — how to stop thinking about what fits on a screen,” he says. “And that will help us make better apps.”

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      Helping customers resolve billing issues without leaving your app

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        As announced in April, your customers will soon be able to resolve payment issues without leaving your app, making it easier for them to stay subscribed to your content, services, and premium features.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        Starting August 14, 2023, if an auto-renewable subscription doesn’t renew because of a billing issue, a system-provided sheet will appear in your app with a prompt that lets customers update the payment method for their Apple ID. You can test this sheet in Sandbox, as well as delay or suppress it using messages and display in StoreKit. This feature is available in iOS 16.4 and iPadOS 16.4 or later, and no action is required to adopt it.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        Learn about the system-provided sheet

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        Learn how to test billing issues in Sandbox

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        List of APIs that require declared reasons now available

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          Apple is committed to protecting user privacy on our platforms. We know that there are a small set of APIs that can be misused to collect data about users’ devices through fingerprinting, which is prohibited by our Developer Program License Agreement. To prevent the misuse of these APIs, we announced at WWDC23 that developers will need to declare the reasons for using these APIs in their app’s privacy manifest. This will help ensure that apps only use these APIs for their intended purpose. As part of this process, you’ll need to select one or more approved reasons that accurately reflect how your app uses the API, and your app can only use the API for the reasons you’ve selected.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          Starting in fall 2023, when you upload a new app or app update to App Store Connect that uses an API (including from third-party SDKs) that requires a reason, you’ll receive a notice if you haven’t provided an approved reason in your app’s privacy manifest. And starting in spring 2024, in order to upload your new app or app update to App Store Connect, you’ll be required to include an approved reason in the app’s privacy manifest which accurately reflects how your app uses the API.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          If you have a use case for an API with required reasons that isn’t already covered by an approved reason and the use case directly benefits the people using your app, let us know.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          View list of APIs and approved reasons

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          Submit a request for a new approved reason

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          Meet with App Store experts

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            Join us for online sessions August 1 through 24 to learn about the latest App Store features and get your questions answered. Live presentations with Q&A are being held in multiple time zones and languages.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            • Explore App Store pricing upgrades, including enhanced global pricing, tools to manage pricing by storefront, and additional price points.
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            • Find out how to measure user acquisition with App Analytics and grow your subscription business using App Store features.
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            • Discover how product page optimization lets you test different elements of your product page to find out which resonate with people most.
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            • Understand how custom product pages let you create additional product page versions to highlight specific features or content.
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            • Learn how to boost discovery and engagement with Game Center and how to configure in-app events.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            Learn more

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            View schedule

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            Take your apps and games beyond the visionOS simulator

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              Apple Vision Pro compatibility evaluations

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              We can help you make sure your visionOS, iPadOS, and iOS apps behave as expected on Vision Pro. Align your app with the newly published compatibility checklist, then request to have your app evaluated directly on Vision Pro.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              Learn more

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              Apple Vision Pro developer labs

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              Experience your visionOS, iPadOS, and iOS apps running on Vision Pro. With support from Apple, you’ll be able to test and optimize your apps for the infinite spatial canvas. Labs are available in Cupertino, London, Munich, Shanghai, Singapore, and Tokyo.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              Learn more

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              Apple Vision Pro developer kit

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              Have a great idea for a visionOS app that requires building and testing on Vision Pro? Apply for a Vision Pro developer kit. With continuous, direct access to Vision Pro, you’ll be able to quickly build, test, and refine your app so it delivers amazing spatial experiences on visionOS.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              Learn more

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              Upcoming price and tax changes for apps, in-app purchases, and subscriptions

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                The App Store’s commerce and payments system was built to empower you to conveniently set up and sell your products and services on a global scale in 44 currencies across 175 storefronts. When tax regulations or foreign exchange rates change, we sometimes need to update prices on the App Store in certain regions and/or adjust your proceeds. These updates are done using publicly available exchange rate information from financial data providers to help ensure prices for apps and in‑app purchases stay equalized across all storefronts.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                On July 25, pricing for apps and in‑app purchases (excluding auto‑renewable subscriptions) will be updated for the Egypt, Nigeria, Tanzania, and Türkiye storefronts. These updates also consider the following tax changes:

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                • Egypt: introduction of a value‑added tax (VAT) of 14%
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                • Tanzania: introduction of a VAT of 18% and a digital service tax of 2%
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                • Türkiye: increase of the VAT rate from 18% to 20%
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                How this impacts pricing
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                • If you’ve selected Egypt, Nigeria, Tanzania, or Türkiye as the base storefront for your app or in‑app purchase (excluding auto‑renewable subscriptions), the price won’t change on that storefront. Prices on other storefronts will be updated to maintain equalization with your chosen base price.
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                • If the base storefront for your app or in‑app purchase (excluding auto‑renewable subscriptions) isn’t Egypt, Nigeria, Tanzania, or Türkiye, prices will increase on the Egypt, Nigeria, Tanzania, and Türkiye storefronts.
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                • If your in‑app purchase is an auto‑renewable subscription or if you manually manage prices on storefronts instead of using the automated equalized prices, your prices won’t change.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                The Pricing and Availability section of My Apps has been updated in App Store Connect to display these upcoming price changes. As always, you can change the prices of your apps, in‑app purchases, and auto‑renewable subscriptions at any time.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                How this impacts proceeds and tax administration

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                Your proceeds for sales of apps and in-app purchases (including auto‑renewable subscriptions) will change to reflect the new tax rates and updated prices. Exhibit B of the Paid Applications Agreement has been updated to indicate that Apple collects and remits applicable taxes in Egypt and Tanzania.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                Learn more about managing your prices

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                Viewing new pricing

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                Selecting a base country or region

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                Pricing and availability start times by region

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                Setting in‑app purchase pricing

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                Providing safe app experiences for families

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  The App Store was created to be a safe and trusted place for users to get apps, and a great business opportunity for developers. Apple platforms and the apps you build have become important to many families, as children use our products and services to explore the digital world and communicate with family and friends. We hold apps for kids and those with user-generated content and interactions to the highest standards. To continue delivering safe experiences for families together, we wanted to remind you about the tools, resources, and requirements that are in place to help keep users safe in your app.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  Made for Kids

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  If you have an app that’s intended for kids, we encourage you to use the Kids category, which is designed for families to discover age-appropriate content and apps that meet higher standards that protect children’s data and offer added safeguards for purchases and permissions (e.g., for Camera, Location, etc).

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  Learn more about building apps for Kids.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  Parental controls

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  Your app’s age rating is integrated into our operating systems and works with parental control features, like Screen Time. Additionally, with Ask To Buy, when kids want to buy or download a new app or in-app purchase, they send a request to the family organizer. You can also use the Managed Settings framework to ensure the content in your app is appropriate for any content restrictions that may have been set by a parent. The Screen Time API is a powerful tool for parental control and productivity apps to help parents manage how children use their devices. Learn more about the tools we provide to support parents to help them know, and feel good about, what kids are doing on their devices.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  Sensitive and inappropriate content

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  Apps with user-generated content and interactions must include a set of safeguards to protect users, including a method for filtering objectionable material from being posted to the app, a mechanism to report offensive content and support timely responses to concerns, and the ability to block abusive users. Apps containing ads must include a way for users to report inappropriate and age-inappropriate ads.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  iOS 17, iPadOS 17, macOS Sonoma, and watchOS 10, introduce the ability to detect and alert users to nudity in images and videos before displaying them onscreen. The Sensitive Content Analysis framework uses on-device technology to detect sensitive content in your app. Tailor your app experience to handle detected sensitive content appropriately for users that have Communication Safety or Sensitive Content Warning enabled.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  Supporting users

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  ​Users have multiple ways to report issues with an app, like Report a Problem. Users can also communicate app feedback to other users and developers by writing reviews of their own; users can Report a Concern with other individual user reviews. You should closely monitor your user reviews to improve the safety of your app, and have the ability to address concerns directly. Additionally, if you believe another app presents a trust or safety concern, or is in violation of our guidelines, you can share details with Apple to investigate.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  These user review tools are critical to informing the work we do to keep the App Store safe. Apple deploys a combination of machine learning, automation, and human review to monitor concerns related to abuse submitted via user reviews and Report a Problem. We monitor for topics of concern such as reports of fraud and scams, copycat violations, inappropriate content and advertising, privacy and safety concerns, objectionable content and child exploitation; and use techniques such as semi-supervised Correlation Explanation (CorEx) models, and Bidirectional Encoder Representations from Transformers (BERT)-based large language models specifically trained to recognize these topics. Flagged topics are then surfaced to our App Review team, who investigate the app further and take action if violations of our guidelines are found.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  We believe we have a shared mission with you as developers to create a safe and trusted experience for families, and look forward to continuing that important work. Here are some resources that you may find helpful:

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  Sensitive Content Analysis framework

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  Learn about Ratings, Reviews, and Responses

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  Report a Trust & Safety concern related to another app

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  Learn about the ScreenTime Framework

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  Learn about building apps for Kids

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  New design resources now available

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    visionOS SDK now available

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      You can now start creating cutting-edge spatial computing apps for the infinite canvas of Apple Vision Pro. Download Xcode 15 beta 2, which includes the visionOS SDK and Reality Composer Pro (a new tool that makes it easy to preview and prepare 3D content for visionOS). Add a visionOS target to your existing project or build an entirely new app, then iterate on your app in Xcode Previews. You can interact with your app in the all-new visionOS simulator, explore various room layouts and lighting conditions, and create tests and visualizations. New documentation and sample code are also available to help you through the development process.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      Download Xcode 15 beta 2

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      Learn about developing for visionOS

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      Spotlight on: Developer tools for visionOS

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        With the visionOS SDK, developers worldwide can begin designing, building, and testing apps for Apple Vision Pro.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        For Ryan McLeod, creator of iOS puzzle game Blackbox, the SDK brought both excitement and a little nervousness. “I didn’t expect I’d ever make apps for a platform like this — I’d never even worked in 3D!” he says. “But once you open Xcode you’re like: Right. This is just Xcode. There are a lot of new things to learn, of course, but the stuff I came in knowing, the frameworks — there’s very little change. A few tweaks and all that stuff just works.”

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        visionOS is designed to help you create spatial computing apps and offers many of the same frameworks found on other Apple platforms, including SwiftUI, UIKit, RealityKit, and ARKit. As a result, most developers with an iPadOS or iOS app can start working with the platform immediately by adding the visionOS destination to their existing project.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        “It was great to be able to use the same familiar tools and frameworks that we have been using for the past decade developing for iOS, iPadOS, macOS, and watchOS,” says Karim Morsy, CEO and co-founder of Algoriddim. “It allowed us to get our existing iPad UI for djay running within hours.”

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        Even for developers brand new to Apple platforms, the onboarding experience was similarly smooth. “This was my first time using a Mac to work,” says Xavi H. Oromí, chief engineering officer at XRHealth. “At the beginning, of course, a new tool like Xcode takes time to learn. But after a few days of getting used to it, I didn’t miss anything from other tools I’d used in the past.”

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        In addition to support for visionOS, the Xcode 15 beta also provides Xcode Previews for visionOS and a brand new Simulator, so that people can start exploring their ideas immediately. “Transitioning between ideas, using the Simulator to test them, it was totally organic,” says Oromí. “It’s a great tool for prototyping.”

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        In the visionOS simulator, developers can preview apps and interactions on Vision Pro. This includes running existing iPad and iPhone apps as well as projects that target the visionOS SDK. To simulate eye movement while in an app, you can use your cursor to focus an element, and a click to indicate a tap gesture. In addition to testing appearance and interactions, you can also explore how apps perform in different background and lighting scenarios using Simulated Scenes. “It worked out of the box,” says Zac Duff, CEO and co-founder of JigSpace. “You could trust what you were seeing in there was representative of what what you would see on device.”

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        The SDK also includes a new development tool — Reality Composer Pro — which lets you preview and prepare 3D content for your visionOS apps and games. You can import and organize assets, add materials and particle effects, and bring them right back into Xcode with thanks to tight build integration. “Being able to quickly test things in Reality Composer Pro and then get it up and running in the simulator meant that we were iterating quickly,” says Duff. “The feedback loop for developing was just really, really short.”

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        McLeod had little experience with 3D modeling and shaders prior to developing for visionOS, but breaking Blackbox out of its window required thinking in a new dimension. To get started, McLeod used Reality Composer Pro to develop the almost-ethereal 3D bubbles that make up Blackbox’s main puzzle screen. “You can take a basic shape like a sphere and give it a good shader and make sure that it's moving in a believable way,” says McLeod. “That goes incredibly far.”

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        The visionOS SDK also brings new Instruments like RealityKit Trace to developers to help them optimize the performance of their spatial computing apps. As a newcomer to using RealityKit in his apps, McLeod notes that he was “really timid” with the rendering system at first. “Anything that's running every single frame, you're thinking, 'I can't be checking this, and animating that, and spawning things. I'm going to have performance issues!'” he laughs. “I was pretty amazed at what the system could handle. But I definitely still have performance gains to be made.”

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        For developers like Caelin Jackson-King, an iOS software engineer for Splunk’s augmented reality team, the SDK also prompted great team discussions about updating their existing codebase. “It was a really good opportunity to redesign and refactor our app from the bottom up to have a much cleaner architecture that supported both iOS and visionOS,” says Jackson-King.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        The JigSpace team had similar discussions as they brought more RealityKit and SwiftUI into their visionOS experience. “Once we got comfortable with the system, it was like a paradigm shift,” says Duff. “Rather than going, ‘OK, how do we do this thing?’, we could be more like, ‘What do we want to do next?’ Because we now have command of the tools.”

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        You can explore those tools now on developer.apple.com along with extensive technical documentation and sample code, design kits and tools for visionOS, and updates to the Human Interface Guidelines.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        Download the visionOS SDK

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        Learn more about developing for visionOS

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        Prepare your apps for visionOS

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        Explore sessions about visionOS

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        WWDC23 resources and survey

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          Thank you to everyone who joined us for an amazing week. We hope you found value, connection, and fun. You can continue to:

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          We’d love to know what you thought of this year’s conference. If you’d like to tell us about your experience, please complete the WWDC23 survey.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          Take the survey

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          WWDC23 highlights

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            Looking to explore all the big updates from an incredible week of sessions? Start with this collection of essential videos across every topic. And as always, you can watch the full set of sessions any time.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            Spatial Computing Principles of spatial design Watch now Meet SwiftUI for spatial computing Watch now Meet UIKit for spatial computing Watch now Design for spatial user interfaces Watch now Get started with building apps for spatial computing Watch now Build great games for spatial computing Watch now Develop your first immersive app Watch now Meet Object Capture for iOS Watch now Meet Safari for spatial computing Watch now Developer Tools What’s new in Xcode 15 Watch now Swift What’s new in Swift Watch now Meet SwiftData Watch now SwiftUI & UI Frameworks What’s new in SwiftUI Watch now What’s new in UIKit Watch now What’s new in AppKit Watch now Design What’s new in SF Symbols 5 Watch now Meet watchOS 10 Watch now Design dynamic Live Activities Watch now Graphics & Games Bring your game to Mac, Part 1: Make a game plan Watch now Your guide to Metal ray tracing Watch now App Store Distribution & Marketing What’s new in App Store Connect Watch now Explore App Store Connect for spatial computing Watch now ML & Vision Discover machine learning enhancements in Create ML Watch now Lift subjects from images in your app Watch now Privacy & Security What’s new in privacy Watch now App Services What’s new in Core Motion Watch now What’s new in Wallet and Apple Pay Watch now Meet StoreKit for SwiftUI Watch now Meet MapKit for SwiftUI Watch now Safari & Web What’s new in Safari extensions Watch now What’s new in web apps Watch now Explore media formats for the web Watch now Accessibility & Inclusion Build accessible apps with SwiftUI and UIKit Watch now Perform accessibility audits for your app Watch now Photos & Camera Discover Continuity Camera for tvOS Watch now Create a more responsive camera experience Watch now Audio & Video What’s new in voice processing Watch now Add SharePlay to your app Watch now System Services What’s new in Core Data Watch now Business & Education Meet device management for Apple Watch Watch now Explore advances in declarative device management Watch now What’s new in managing Apple devices Watch now Health & Fitness Build custom workouts with WorkoutKit Watch now Build a multi-device workout app Watch now

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              Friday @ WWDC23

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                The final day of WWDC is upon us — but before we power down, here's a look at some of the activities and sessions available today.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                Get ready for day five

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                We’ve saved some of the best for last. Pop into Slack to learn more about Metal, meet some super SwiftUI presenters, and explore spatial computing.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                Q&A: Games for visionOS View now Q&A: Bring your ARKit app to visionOS View now Q&A: SwiftUI for visionOS View now Q&A: Spatial design View now Q&A: Metal View now Meet the presenters: Design with SwiftUI View now

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                In today’s new sessions, you can learn to animate with springs, explore Core Motion, and get a taste of the SwiftUI cookbook for focus.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                Animate with springs Watch now What’s new in Core Motion Watch now The SwiftUI cookbook for focus Watch now Elevate your windowed app for spatial computing Watch now

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                It’s your last chance to take part in Dev Tools Trivia Time! Plus, make new friends at the Friday icebreaker.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                Dev Tools Trivia Time View now Immersive icebreaker View now Check out podcasts from WWDC

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                Catch up on the week with podcasts from developers and developer advocates, recorded at Apple Park.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                Apple Bitz XL

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                Connected

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                The Vergecast

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                Waveform

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                Send us your feedback

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                We’d love to know what you liked about WWDC23 — and how we can do even better. Send in your feedback about this year’s conference.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                Take the WWDC23 survey

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                And that's a wrap!

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                Thanks for being part of another incredible WWDC. It’s been a fantastic week of meeting and celebrating, connecting online through labs and activities, and exploring all the new sessions. We appreciate the opportunity to share all of this with you.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                Meet three winners of the 2023 Swift Student Challenge

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  Every year, the Swift Student Challenge recognizes students all over the world who’ve created remarkable app playgrounds.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  The 2023 edition drew submissions from more than 30 countries and regions, and covered topics as varied as healthcare, sports, entertainment, and the environment. And while the submissions were diverse, their creators had a common goal: To share their passions with the world through coding.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  Coding gives me the freedom to feel like an artist — my canvas is the code editor, and my brush is the keyboard.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  Yemi Agesin, 2023 Swift Student Challenge winner

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  This year, Apple increased the number of winners from 350 to 375 to recognize even more students for their artistry and ingenuity — and we’re proud to introduce three of them. Meet first-time Swift Student Challenge winners Asmi Jain, Yemi Agesin, and Marta Michelle Caliendo.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  Read the full story on Apple Newsroom

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  Thursday @ WWDC23

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    Day four is here — and a fresh round of sessions, labs, and activities await.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    Get started with labs and sessions

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    Curious about the difference between the Shared Space and a Full Space in visionOS? Want to learn more about Observable? There’s a Q&A for that. Kick off another full day by chatting with engineers and designers about SwiftUI, Xcode, and all things spatial.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    Q&A: SwiftUI for visionOS View now Q&A: Build UIKit apps for visionOS View now Q&A: Bring your ARKit app to visionOS View now Q&A: SwiftUI View now Q&A: Xcode View now

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    We’ve got incredible new sessions on Live Activities, Metal, spatial experiences, and more.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    Design dynamic Live Activities Watch now Optimize GPU renderers with Metal Watch now Explore rendering for spatial computing Watch now Create a great spatial playback experience Watch now

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    And there are even more exciting activities happening today, including an informal icebreaker and another fierce round of Dev Tools Trivia Time.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    Immersive icebreaker View now Dev Tools Trivia Time View now

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    If you haven’t signed up for a one-on-one lab this week, time is running out! Today is your last day to request an appointment for Friday. To make a request, visit the WWDC tab in the Apple Developer app or go to the WWDC labs webpage. App Store labs are also available in Chinese, Japanese, and Korean.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    Learn more about labs at WWDC23

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    Download the new Figma design kit

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    Now, by popular demand, you can download an all-new iOS and iPadOS design kit for Figma.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    Apple Design Resources – iOS 17 and iPadOS 17

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    Discover documentation and sample code

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    Browse new and updated documentation and sample code to learn about the latest technologies, frameworks, and APIs introduced at WWDC23. You’ll find new ways to enhance your apps targeting the latest platform releases.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    Apple Developer Documentation

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    Browse portraits of the 2023 Apple Design Award winners

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    We snapped some great portraits of our Apple Design Award-winning developers at Monday’s ceremony. Take a look at all 12 below, and then dive deeper into the stories of their apps through our Behind the Design series.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    Behind the Design: 2023 Apple Design Awards View now

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    Evan Kice, Afterplace

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    Luke Beard, Any Distance

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    Bob Meese, Duolingo

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    Philipp Nägelsbach, Endling

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    Ryan Jones, Flighty

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    Jeff Birkeland, Headspace

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    Ben Brode, MARVEL SNAP

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    Luke Spierewka, Railbound

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    Tsuyoshi Kanda, Resident Evil Village

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    Jakob Lykkegaard, stitch.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    Swupnil Sahai, SwingVision

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    Joseph Cohen, Universe

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    Have fun out there, and we’ll catch you tomorrow for the final day of WWDC!

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    Discover documentation and sample code

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      Browse new and updated documentation and sample code to learn about the latest technologies, frameworks, and APIs introduced at WWDC23. You’ll find new ways to enhance your apps targeting the latest platform releases.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      Explore highlights of new technologies introduced at WWDC23

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      Wednesday @ WWDC23

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        Two days are in the books — and there’s so much more to come. Get ready for another big day at WWDC.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        Dive into sessions and activities

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        Start off in Slack, where you can connect with Apple engineers and designers on spatial design, WidgetKit, machine learning, 3D content, and much more.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        Q&A: Spatial design View now Q&A: WidgetKit View now Q&A: Machine learning open forum View now Q&A: Create 3D content for Apple platforms View now

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        We’ve also posted new sessions on topics like SwiftUI, widgets, SwiftData, and Xcode test reports.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        Design with SwiftUI Watch now Bring widgets to life Watch now Build an app with SwiftData Watch now Fix failures faster with Xcode test reports Watch now

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        Test your knowledge in Dev Tools Trivia Time, WWDC’s fiercest competition! And come hang out with the SwiftUI team and chat about sessions, meet other members of the community, and share tips and tricks.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        Dev Tools Trivia Time View now Break the SwiftUIce View now

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        There’s still time to request lab appointments to meet one-on-one with experts about technology, design, app review, the App Store, and more. To make a request, visit the WWDC tab in the Apple Developer app or the go to the WWDC labs webpage.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        Learn more about labs at WWDC23

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        A sneak peek at the visionOS SDK

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        Developers attending the special event at Apple Park visited the Apple Developer Center on Tuesday to learn more about building apps for Apple's new spatial operating system. “Going in, I was under the impression it was going to be tricky, or hard, or ‘where do I start?’” says Paul Hudson, iOS developer and founder of Hacking with Swift. “But actually — if you take what you know and add a little bit, you can make something good and then increment from there. It doesn’t take much to get something great. That’s my main takeaway.”

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        Find out how developers of apps like djay, Blackbox, JigSpace, and XRHealth are starting to build for spatial computing.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        Learn more about developing for visionOS

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        Spotlight on: Developing for visionOS View now 你好,こんにちは、Human Interface Guidelines!

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        The Human Interface Guidelines are now available in Chinese and Japanese! And you can check out updated design recommendations for watchOS, App Shortcuts, widgets, and all the latest platform releases.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        Human Interface Guidelines

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        Enjoy your day and we’ll catch you tomorrow for day four!

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        Tuesday @ WWDC23

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          Welcome to day two of WWDC! There’s more than ever to explore this week: Xcode is getting updated, SwiftUI is getting animated, and — did we mention? — apps are getting a lot more spatial. Here’s a guide to what happened yesterday and what’s on tap today.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          Catch up on day one

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          For the second year in a row, we welcomed more than 1,000 developers to Apple Park for the WWDC keynote and Platforms State of the Union to learn about the future of Apple platforms.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          With new frameworks, a new spatial operating system, and new hardware designed for developers, there’s an incredible amount to dig into this year. Catch up quickly with this recap of the most important big (and little!) moments from the keynote:

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          17 big & little things at WWDC23 Watch now

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          Want the complete experience? Here are the full replays for each event.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          Keynote Watch now Platforms State of the Union Watch now Meet Apple Vision Pro

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          On day one of WWDC, you got a peek at visionOS, Apple’s new spatial operating system — and that was just the beginning. There are familiar and new frameworks to learn, new tools like Reality Composer Pro to explore, and new in-person programs coming soon.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          Learn more about developing for visionOS

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          Prepare your apps for visionOS

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          Explore sessions about visionOS

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          Start your Tuesday

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          We’re off and running with with more than 60 sessions, 100 online activities, and the opportunity to schedule one-on-one lab appointments with Apple experts. Here’s a quick look at all we’ve got in store:

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          What Apple developers need to know at WWDC23 Watch now

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          Need a place to start? Check out the latest updates to watchOS 10, an introduction to SwiftData, and the principles of spatial design.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          Meet watchOS 10 Watch now Meet SwiftData Watch now Principles of spatial design Watch now

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          New this year: Many session videos now offer chapter markers, so you can skip right to the content you’re looking for. (You’ll find chapter markers for the keynote, as well.)

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          Join us in Slack to connect with the presenters of sessions like “Meet SwiftUI for spatial computing” and “What’s new in SwiftUI” and join Q&As about game design, Xcode 15, and much more.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          Meet the presenter: Meet SwiftUI for spatial computing View now Meet the presenters: What’s new in SwiftUI View now Q&A: Games View now Q&A: Xcode View now

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          Dev Tools Trivia Time is bigger and better than ever — test your knowledge in WWDC’s fiercest competition!

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          Dev Tools Trivia Time View now

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          And connect with Apple experts directly by requesting one-on-one lab appointments for answers to your questions about technology, design, and maximizing your App Store presence. To make a request, visit the WWDC tab in the Apple Developer app or go to the WWDC labs webpage.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          Learn more about labs at WWDC23

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          Congrats to the 2023 Apple Design Award winners

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          Yesterday, we handed out the 2023 Apple Design Awards and added 12 new titles to the list of the greatest apps and games ever created for Apple platforms. Check out the complete list of 2023 winners and finalists below. Then, get up close and personal with the winning developers, designers, and teams in our Behind the Design series.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          Meet the 2024 Apple Design Award winners

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          Behind the Design: 2023 Apple Design Awards View now Press play: WWDC23 playlists are here

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          Lastly, here’s an audio gift for you! Spin up our official playlists — the perfect soundtrack to an incredible week.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          Playlist: WWDC 2023

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          Playlist: WWDC23 Power Up

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          Playlist: WWDC23 Coding Focus

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          Playlist: WWDC23 Coding Energy

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          Playlist: WWDC23 Coding Chill

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          That's it for now. Have a great day, and we'll see you tomorrow!

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          Sign up for WWDC23 labs and activities

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            Online labs and activities are a great way to connect with Apple engineers, designers, and experts all week long.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            One-on-one labs

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            Get personalized guidance about development basics, complex concepts, and everything in between. Learn how to implement new Apple technologies, explore UI design principles, improve your App Store presence, and much more.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            Activities

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            There are plenty of exciting activities happening daily on Slack.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            • Ask engineering and design questions in Q&As.
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            • Join or follow real-time conversations while watching session videos together, and stay for a Q&A with the presenter.
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            • Get to know other developers and teams from Apple in community icebreakers.
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            • Test your trivia expertise starting on June 6.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            Labs and activities are open to all members of the Apple Developer Program and Apple Developer Enterprise Program, as well as 2023 Swift Student Challenge applicants.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            Register for labs

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            Register for activities

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            Learn about WWDC23

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            Behind the Design: 2023 Apple Design Awards

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              Every year, the Behind the Design series takes a special look at the remarkable teams behind the Apple Design Award-winning apps and games. Read on to meet 12 incredible teams from around the world and learn how they brought their winning ideas to life.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              Winners in the category provide a great experience for all by supporting people from a diversity of backgrounds, abilites, and languages.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              App

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              Universe

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              Launched in 2017, the powerful, versatile, and almost unbelievably simple Universe makes creating a website as easy as building with blocks. The app operates on a grid system. To create a site, add blocks to the grid, and to edit a site, move those blocks around. The app doesn’t just remove barriers, it bulldozes them. “Our goal is making this technology available to everybody,” says founder Joseph Cohen.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              Behind the Design: Universe View now

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              Game

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              stitch.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              For all its many genres and styles, the gaming world has been awfully threadbare when it comes to experiences about embroidery. That all changes with stitch., a charming cross between casual puzzler, meditative exercise, and afternoon craft project — and as cross-generational a game as you’re likely to find. “We pride ourselves on making games that anyone can play,” says Jakob Lykkegaard, founder of Lykke Studios, the team behind stitch. “It’s important to spend the time to make them available for everyone.”

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              Behind the Design: stitch. View now

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              Winners in this category provide memorable, engaging, and satisfying experiences that are enhanced by Apple technologies.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              App

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              Duolingo

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              What makes Duolingo such an engaging way to learn a language? The answer is hiding in plain sight. “The secret to Duolingo is that we’re not an education company. We’re a fun and motivation company,” says Ryan Sims, VP of design. “Fun is the most important part of the work we do.”

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              Behind the Design: Duolingo View now

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              Game

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              Afterplace

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              At first glance, Evan Kice’s Afterplace appears to have time-traveled from the late 1980s. But it’s a decidedly modern game too — fast, fluid, and incredibly easy to pick up. Enemies lurk everywhere and levels stretch out in all directions; what looks like a humble library is secretly a multilevel maze. “I always loved it when a game just kept going,” says Kice. “I was fascinated by the idea that a game could hold an entire country.”

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              Behind the Design: Afterplace View now

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              Winners in this category deliver intuitive interfaces and effortless controls that are perfectly tailored to their platform.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              App

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              Flighty

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              Flighty might be the easiest thing travelers navigate on their entire trip. “Travel can be a high-stress situation,” says Ryan Jones, the Austin-based developer who founded the app in 2019. “We want Flighty to work so well that it feels almost boringly obvious.”

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              Behind the Design: Flighty View now

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              Game

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              Railbound

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              In Railbound, players are challenged to link train cars in proper order by laying down track through a mechanic that’s as simple as finger painting. “I pay a lot of attention to input,” says Luke Spierewka of the game’s Afterburn studio. “For Railbound, I wanted a system where you basically paint rail tiles with one finger.”

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              Behind the Design: Railbound View now

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              Winners in this category improve lives in a meaningful way and shine a light on crucial issues.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              App

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              Headspace

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              Few apps have made mindfulness as accessible as Headspace. More than a decade since its launch, the app continues to set the standard for mental health apps. “Mindfulness, meditation, mental health — none of these are easy to navigate,” says Jeff Birkeland, senior vice president for member products. “An app that feels warm, friendly, and easy to use can provide approachable support for tough issues.”

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              Behind the Design: Headspace View now

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              Game

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              Endling

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              Endling is a 3D adventure in which you play as a fox navigating a land charred by environmental disaster and human impact. It’s also a powerful mix of medium and message. “It’s a survival game, but a simplified one that focuses more on telling a story,” says Philipp Nägelsbach, game designer and producer at HandyGames.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              Behind the Design: Endling View now

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              Winners in this category feature stunning imagery, skillfully drawn interfaces, and high-quality animations that lend to a distinctive and cohesive theme.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              App

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              Any Distance

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              Luke Beard, the Atlanta-based designer who created Any Distance with engineer Daniel Kuntz, says the app is “for everyone, not just athletes.” Their app is a design-forward fitness tracker and social network that delivers workout stats in beautiful and shareable formats — dynamic charts and graphs, animated 3D maps, AR experiences, and gorgeous cards — that can integrate photos. And its name is also its philosophy: Any distance counts, not just a swim or bike ride, but a walking meeting, stroller run, or its most popular option, a dog walk.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              Behind the Design: Any Distance View now

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              Game

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              Resident Evil Village

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              The horror adventure comes to Mac with Apple silicon, with all the visual achievements fans of the long-running series could hope for. From its creepy castle to its decrepit factories to its magnificently hideous villains, Resident Evil Village offers some of the most realistic graphics ever seen on Apple devices. “The concept was a horror theme park with unique characters that stand out against a beautiful environment,” says producer Tsuyohi Kanda.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              Behind the Design: Resident Evil Village View now

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              Winners in this category provide a state-of-the-art experience through novel use of Apple technologies that set them apart in their genre.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              App

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              SwingVision

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              When Swupnil Sahai started creating SwingVision, he had no app-building experience — but he’d played a lot of tennis. “The initial idea was, ‘Maybe we can use the accelerometer and gyroscope on Apple Watch to figure out how fast I’m swinging, and maybe we can use the [Apple Watch] screen to keep score,’” says Sahai. “That was really it.” Today, SwingVision has become an integral part of the tennis community.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              Behind the Design: SwingVision View now

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              Game

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              MARVEL SNAP

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              MARVEL SNAP reboots the collectible card game genre with brisk gameplay, a wild cast of superheroes, and its “snap” mechanic, a double-or-nothing bet that adds whole new layers of strategy-slash-psychological warfare. “Our goal as designers is to maximize that ratio of complexity and depth,” says Ben Brode, chief development officer for Second Dinner.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              Behind the Design: MARVEL SNAP View now

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              Behind the Design: Universe

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                As a kid, Universe founder Joseph Cohen loved nearly everything about the internet: how it brought people together, created avenues for his twin passions of creativity and commerce, and democratized the flow of information. “I grew up in New York,” Cohen says, “but I like to say that I really grew up on the internet.”

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                Today, Cohen’s passion is still the internet — but he’s no longer just living in it. He’s striving to improve it. “Our goal is making this technology available to everybody,” he says.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                The website-building app Universe has been used to create countless storefronts — like this one.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                Launched in 2017, the powerful, versatile, and almost unbelievably simple Universe makes creating a website as easy as building with blocks. The app operates on a grid system. To create a site, add blocks to the grid, and to edit a site, move those blocks around. No knowledge of coding, design, or publishing is necessary — Universe even handles the process of acquiring and publishing to specific domain names. The app doesn’t just remove barriers, it bulldozes them. And today, Universe currently powers storefronts, artist portfolios, musician pages, community group hubs, personal web presences, and everything in between.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                In the past year, Universe empowered more people than ever with a series of accessibility upgrades directly inspired by people’s feedback. In one example, a high-school student in California who is blind reached out to ask for better VoiceOver support — and the Universe team quickly came up with an elegant idea.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                Joseph Cohen, Universe

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                “We learned that the grid system we designed is perfectly fitted to screen readers,” he says. “VoiceOver works by reading from the top left of the page, so when you have a grid-based coordinate system, it will walk right through what’s on the screen. It’ll say, ‘OK, in position one and two, you have an image of flowers,’ and so forth.”

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                The team refined the feature by working closely with a number of people who are blind or have low vision — many of whom have Universe-created sites online right now. And they kept going, adding Dynamic Type to scale text as well as accessibility upgrades to the app’s general navigation, settings, audience metrics, and more.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                Universe’s grid system really is this simple.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                The team's latest project aims to make it even easier for anyone to get started with web design. Cohen and team are working on an AI feature that will instantly generate or refine a custom website based on natural language descriptions. Tell Universe, “Make a pink site with sparkles for my custom nail business in Chicago,” and the results will appear in seconds.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                Our goal is making this technology available to everybody.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                Joseph Cohen, Universe founder

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                “It’ll be a dialogue; it’s not a one-way street,” says Cohen. “You can still edit your site manually, or you can ask it to change the theme or background color.” (The AI designer is named GUS, both because it stands for “generative Universe sites” and because Universe employs a very skilled designer named Gus. “We have to call him Human Gus now,” laughs Cohen.)

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                Cohen plans to build the AI feature “in public,” releasing regular video updates about the team’s progress as part of a way to garner people’s feedback on the fly. It’s another example of his drive to make the app — and the internet — more open to everyone. “I still live in New York, and the best part of New York is that it’s incredibly diverse,” he says. “It’s gritty and organic and very human. I think the internet can look like that — but you need great tools to enable it.”

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                Learn more about Universe

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                Download Universe - Website Builder from the App Store

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                Behind the Design is a series that explores design practices and philosophies from each of the winners of the Apple Design Awards. In each story, we go behind the screens with the developers and designers of these award-winning apps and games to discover how they brought their remarkable creations to life.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                Explore more of the 2023 Behind the Design series

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                Behind the Design: Duolingo

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  What makes Duolingo such an engaging way to learn a language? The answer is hiding in plain sight. “The secret to Duolingo is that we’re not an education company. We’re a fun and motivation company,” says Ryan Sims, VP of design. “Fun is the most important part of the work we do.”

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  More than a decade since its launch, Duolingo continues to boast best-in-class design, great interactions, and an easy-to-follow UI. It’s filled with fun touches, like gamified lessons, hilarious characters, and a learning path that leans on actual conversations. And then there’s Duo, the famously tenacious owl mascot who achieved viral notoriety for his skill at encouraging people to extend their learning streaks. The app has figured out how to make a daily language lesson feel not like classwork but a joy.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  The ever-entertaining Duo is an owl of many moods.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  This past year, Duolingo launched a major learning path redesign. In previous versions, it focused on a main screen — known as “the tree” — that let people explore numerous routes. “Two people could spend the same number of hours doing the same number of lessons, but end up in different places,” says Sims. Today, all Duolingo users follow a single route. “We call it ‘the path,’” says Sims. “It was a complete reboot of our product strategy.”

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  The path redesign coincided with another important update: animations for Duolingo’s wonderful cast of characters. There’s Lily, a perpetually unimpressed teen with a dismissive slow-clap; Oscar, a dramatic teacher who takes his job very seriously; and Eddy, a fitness buff with an enthusiasm for just about everything. Their subtle animations when people get something right are a reward in themselves. “A lot of that character interaction was informed by seeing how people connected with Duo,” says Sims.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  The secret to Duolingo is that we’re not an education company. We’re a fun and motivation company.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  Ryan Sims, Duolingo VP of design

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  Filling the app with memorable personalities required world-building — a process not often found in language apps. “It’s such a gigantic task,” says Sims, “and it really just started with our head of art, Greg Hartman, who began drawing characters and saying, ‘Wouldn’t it be cool if you encountered the same people through the entire experience?’” And of course, there’s a team of experts on hand to make sure every character’s story is consistent. “There are quite a few people whose job is to help write these stories and make sure they don’t contradict each other,” says Sims, with a laugh.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  Even in early sketches of Duolingo’s widgets, Duo’s personality shines through.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  Duolingo’s approach under the hood may have changed, but the sense of fun is still front and center.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  The lessons are brisk and breezy, emphasizing the building blocks of language through repeated phrases and sentences. And it’s all designed not just to attract learners, but to get them to stick around through quick lessons, compelling rewards, and unapologetic encouragement to keep their streaks alive. “You learn a language to connect to another human. That’s all it comes down to,” says Sims. “That’s why we’re passionate about teaching folks to speak new languages — because it brings everyone together.”

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  Learn more about Duolingo

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  Duolingo

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  Behind the Design is a series that explores design practices and philosophies from each of the winners of the Apple Design Awards. In each story, we go behind the screens with the developers and designers of these award-winning apps and games to discover how they brought their remarkable creations to life.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  Explore more of the 2023 Behind the Design series

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  Behind the Design: MARVEL SNAP

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    MARVEL SNAP reboots the entire collectible card game universe.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    The game is stacked with incredible visuals, a multiverse of gameplay variations, and a “snap” mechanic — a double-or-nothing bet — that’s as simple as it is revolutionary. It’s got an encyclopedic collection of iconic and deep-cut Marvel characters, but players don’t need a background in comic-book lore or collectible card games in order to participate. And with brilliantly intuitive touch controls and speedy gameplay, it’s perfect for mobile devices.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    MARVEL SNAP is a simple game, but with an incredible array of cards, characters and locations, it also offers near-infinite complexity.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    MARVEL SNAP is the brainchild of Ben Brode and Hamilton Chu, the masterminds behind Hearthstone, which itself redefined the collectible card genre upon its 2014 release. In 2018, the duo launched their own studio, Second Dinner, with big aspirations and an even bigger problem: “We didn’t have any ideas,” laughs Brode, the studio’s chief development officer. “It’s a little terrifying to sit down at your new job and think, ‘OK, we have to come up with a game, and we have nothing.’”

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    Ben Brode, MARVEL SNAP

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    To break their creative block, Brode and Chu started playing every board game they could get their hands on. “That’s the soup that SNAP arose from,” Brode explains. It also led them to the early breakthrough — what Brode calls Chu’s genius idea — that would define the game. “He said, ‘You know what would be really fun? Incorporating the doubling cube from backgammon,’” says Brode. "We tried it and immediately realized we were onto something.”

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    From there, things moved fast. The pair had inked a deal with Marvel, so they sat down to think about what made Marvel special. “It’s the conflict between heroes and villains, right?” he continues. “It’s not about mowing down enemies, it’s about that heroic 1v1 standoff. So we said, ‘That’s it. Let’s try a card game.’” The pair played the earliest rounds of SNAP on the back of business cards and the game’s foundations were established in all of two days.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    To start building MARVEL SNAP, Brode and Chu wrote character names and powers on the back of business cards. ©MARVEL

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    While the core game was built fast, the iterations took much longer. Over the next four years, Second Dinner played, refined, and simplified — to a degree. “It was honestly less about making the game simple and more about maximizing the depth of the complexity we chose to add,” Brode says.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    On one hand, SNAP is an incredibly simple game with one card type, three locations, and six turns. Rules for those card types and locations are easy to follow. Battles last a matter of minutes.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    But those basic components combine for a game of near-infinite complexity — and perfectly calibrated balance. “Most people misunderstand randomness by thinking of it as a scale,” Brode says. “That absolutely is not how randomness works. While no two games of SNAP are alike, in every game you have to think: ‘How can I win this time?’ It’s about the intersection between randomness and skill. And if you lose, you always have an opportunity to reflect on how you could have done something differently.”

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    While no two games of SNAP are alike, in every game you have to think: ‘How can I win this time?’ It’s about the intersection between randomness and skill.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    Ben Brode, MARVEL SNAP creator

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    Even the game’s language keeps players engaged. For instance, retreating in SNAP isn’t necessarily an admission of defeat; it might be a considered decision to minimize loss. “If you decide to leave because it’s strategically correct, that’s not losing!” says Brode. As such, players who retreat get a screen that says “Escaped!” — a much more palatable outcome than losing. “‘Escaped’ zeroes out the emotional negativity,” Brode notes.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    As befitting its comic-book origins, SNAP is a visual feast. Characters have their own unique animations, like Ghost Rider using his chain to yank a discarded card back into the match or Devil Dinosaur unleashing a board-rattling roar. Players can even enable a 60 fps setting to make a Hulk smash look truly incredible. Even “snapping” an opponent triggers a dramatic light show and haptic feedback.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    While SNAP certainly includes top-line Avengers, it also prominently features characters drawn from all corners of the Marvel universe.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    While SNAP certainly includes top-line Avengers, they’re by no means the game’s heaviest hitters. Big wins can come courtesy of characters like Blue Marvel, Mister Fantastic, Misty Knight, and Enchantress — names you’ve maybe not heard in a while, if you’ve heard them at all. Brode says showcasing lesser-known characters was part of the strategy to appeal to a wider audience, but also a nod to his own comic-book past. (Naturally, those who worked on the game also have their favorites — art director Jomaro Kindred is a big Black Panther fan, while producer Gareth Ackerman is really into Armor.)

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    It’s a comic-book game for non-comic-book people, a collectible card battler for those who’ve never heard the phrase, and an incredible achievement that appeals to players of all ages. “I got a suggestion this week from a 5-year-old in Wales who had an idea for a new location,” says Brode. “His parents forwarded it to me with a note that said, ‘We play this together as a family, and he’s learning numbers and math through this game and these characters.’ That’s incredibly rewarding, and it feels awesome.”

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    Learn more about MARVEL SNAP

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    Download MARVEL SNAP from the App Store

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    Behind the Design is a series that explores design practices and philosophies from each of the winners of the Apple Design Awards. In each story, we go behind the screens with the developers and designers of these award-winning apps and games to discover how they brought their remarkable creations to life.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    Explore more of the 2023 Behind the Design series

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    Behind the Design: Afterplace

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      At first glance, Evan Kice’s Afterplace appears to have time-traveled from the late 1980s. It’s a 2D top-down pixelated adventure game full of blocky characters, blippy music, and retro typefaces. If you were ever into the games of the era — and Kice very much was — it feels like a delightful visit from an old friend.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      “I grew up on those games,” says Kice. “I was always carrying them around. And I was also the kind of kid who’d look at a manhole cover and think, ‘That is definitely the entrance to a dungeon.’”

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      Yet for all its nostalgia, Afterplace is a decidedly modern game too. It’s fast, fluid, incredibly easy to pick up, and features a surprisingly huge map. Its characters look like 1989 but talk like 2023, especially the sarcastic vending machine that dispenses random jokes and the friendly rabbit that provides advice. (For instance: “If you think something’s going to attack you, don’t be there anymore. Like, move away.”)

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      Afterplace is filled with memorable characters, like the friendly rabbit that dispenses helpful advice.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      It’s especially impressive when you realize that Kice is the game’s sole designer, developer, and artist. He began making video games at age 11, studied software engineering in college, and took a few game design courses. But mostly, he taught himself along the way. “Honestly, I just watched a lot of tutorials,” he says. “YouTube is how I learned art, sound, music, and basically everything that wasn’t programming or game design.”

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      Evan Kice, Afterplace

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      The game is also brilliantly designed for mobile, with one-finger controls that make it easy to explore. Tap to interact with an object or slash your way out of trouble. Or tap and drag anywhere on the screen to move around. In fact, one of Kice’s earliest design decisions was to lean on touch screen interaction paradigms instead of drawing controls on screen. “I was never a fan of virtual buttons or d-pads,” says Kice. “I’ve played a lot of those kinds of games, and often ended up going a direction I didn’t want to go. And I personally enjoyed being able to play with one thumb while standing in line somewhere.”

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      That drive for simplicity also informed the interactions between hero and enemy. “Some games have simple enemies but a complex you,” he says. “Afterplace has a simple you but complex enemies. Whenever you walk up to something, you have to say, ‘What is this guy gonna do? I gotta figure this out.’ That’s your whole job. You’re not worried about doing double backflips because you’re too busy trying not to get smashed in the face.”

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      Afterplace’s huge map is packed with forests, towns, and scary monsters.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      Enemies lurk everywhere in Afterplace’s massive worlds. Levels stretch out in all directions; what looks like a humble library is secretly a multilevel maze. “I always loved it when a game just kept going,” says Kice. “I was fascinated by the idea that a game could hold an entire country.”

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      I was never a fan of virtual buttons or d-pads. And I personally enjoyed being able to play with one thumb while standing in line somewhere.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      Evan Kice, Afterplace creator

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      He was also fascinated by vintage heroes and villains. “All the characters in Afterplace are the same resolution as the characters in my favorite childhood games,” he says. “I really, really loved those characters. But they were just static images; they faced four directions and had a blank stare on them. As a kid, I would think, ‘I would love it if they did anything more than stand in place and say one line of dialogue.” Inspired, he challenged himself on Afterplace to see how expressive that vintage resolution could be. “Turns out they’re pretty expressive!” he laughs.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      Evan Kice’s early Afterplace sketches show the beginnings of his game’s expansive world.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      Afterplace’s expressiveness comes through in its clever dialogue, like the character who encourages players to be more strategic in their attacks by saying, “You wouldn’t imagine how many dunderheads just keep swingin’ away at a monster.” The game’s music — which Kice wrote and performed — starts in an 8-bit style but expands to become more orchestral later on, a trick he picked up from the game Undertale. “If you start out the game with a retro sound, then later break out the string quartet or horror violins, it has a lot more impact,” he says. “The rest of the game has maybe three melodies in it. I’ll pretend that’s because I’m a cool designer using leitmotifs, but it’s actually the maximum number of melodies I could think of.”

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      A rendering of Clover, one of Afterplace’s many memorable characters.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      Never a fan of intro cutscenes, Kice designed Afterplace’s onboarding to get players right into the action. “I love story in games, but I almost always skip those introductions. I’m just not invested yet," he says.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      Afterplace also features a bevy of accessibility options that let players adjust text scaling, camera shake amount, contrast, and more. There’s even an invincibility mode, if players are really having trouble with those monsters. It’s all part of a strategy to appeal to anyone, regardless of their video game history — if they have one at all.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      I love story in games, but I almost always skip those introductions.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      Evan Kice, Afterplace creator

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      Afterplace is very niche," he says. It’s for people who maybe don’t play games on mobile. But if it helps bring more people into gaming, I think that’s great.”

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      Learn more about Afterplace

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      Afterplace

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      Behind the Design is a series that explores design practices and philosophies from each of the winners of the Apple Design Awards. In each story, we go behind the screens with the developers and designers of these award-winning apps and games to discover how they brought their remarkable creations to life.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      Explore more of the 2023 Behind the Design series

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      Behind the Design: SwingVision

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        When Swupnil Sahai started creating SwingVision, he had no app-building experience — but he’d played a lot of tennis.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        “The initial idea was, ‘Maybe we can use the accelerometer and gyroscope on Apple Watch to figure out how fast I’m swinging, and maybe we can use the Apple Watch screen to keep score,’” says Sahai from his workspace in the Bay Area. “That was really it.”

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        SwingVision’s easy-to-navigate UI makes it useful for both officially sanctioned matches and weekend practice.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        The app was a true passion project for Sahai, who jumped into SwingVision pretty much cold. “Although I’d programmed in other languages, Swift seemed much more approachable, so I thought 'Maybe I can pick this up on my own.’” He not only picked it up, he found the learning curve so speedy and enjoyable that he was staying up later and later to plunge into SwingVision and Swift. “I was building in Xcode on day one,” he says. “I don’t think I’ve ever had so much fun working.”

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        Today, SwingVision has become the definitive tennis app, and an incredible example of the combined power of cameras, machine learning, and the concept of filling a need. It’s beautifully and exclusively designed for iOS, with an easy-to-navigate UI that makes it accessible to both officially sanctioned matches and people practicing on the weekends.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        Swupnil Sahai, SwingVision

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        It’s also become an integral part of the tennis community. SwingVision is now used for line calling, the definitive say on whether a ball is in or out — a call that’s still left to players themselves. “It’s rare to have judges on the court in tennis,” says Sahai. “In baseball, you have umpires. Even middle-school basketball has referees. Somehow in tennis you have to do everything yourself.”

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        I was building in Xcode on day one. I don’t think I’ve ever had so much fun working.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        Swupnil Sahai, SwingVision founder

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        Founded in 2015 by Sahai, along with close friend and current CTO Richard Hsu, the app couldn’t be simpler. Point your iPhone or iPad camera at the court and SwingVision tells you how fast you’re serving, the consistency of your shots, and how to shape up your posture and footwork. It does so by using advanced machine learning to track shots (a pretty intensive process). “It allows you to call lines more accurately than you could with your own eyes. But if you don’t record at 60 fps, you won’t even see the ball bounce — it just moves too fast,” he says. “Of course, 1080p video is very, very high resolution. It’s something like 2 million pixels that all have to be processed 60 times a second. We had to innovate a lot to make these models as lean as possible. This app is basically not possible without Neural Engine.”

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        SwingVision can be the definitive say on line calling. (In!)

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        SwingVision, now powered by a team of 23, has evolved quite a bit. Players can now stream matches live — both the video and the on-screen data — and afterward, the app creates an easily shareable highlight reel. One of its latest features sets up “target zones” on the court to help players practice their serves — a great example of how the video-centric app integrates tightly with Apple Watch. “Serving is traditionally the most boring thing to practice,” laughs Sahai. “So we gamified it with different sound effects and a progress monitor on Apple Watch. Even with all our video, Apple Watch is still critical because it elevates the experience.”

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        In addition to driving the success of his app, Sahai shares his development expertise by continuing to teach a UC Berkeley course called Data 8: Foundations of Data Science — currently the largest class on campus. He’s known as “the SwingVision guy.” “Sometimes I’ll see a post from a student that says, ‘Wait, you made that?’” he laughs. “The community there is very supportive.”

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        Learn more about SwingVision

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        Download SwingVision from the App Store

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        Behind the Design is a series that explores design practices and philosophies from each of the winners of the Apple Design Awards. In each story, we go behind the screens with the developers and designers of these award-winning apps and games to discover how they brought their remarkable creations to life.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        Explore more of the 2023 Behind the Design series

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        Behind the Design: Headspace

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          Few apps have made mindfulness as accessible as Headspace.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          More than a decade since its launch, the app continues to set the standard for mental health apps — an especially notable accomplishment, as it can be difficult to communicate challenging topics like mindfulness and mental health through an app. "Demystification is a word we use a lot,” says Jeff Birkeland, Headspace senior vice president and general manager for member products. “Mindfulness and mental health can seem complex, perhaps mystical, maybe even inaccessible. So how do we make it approachable and friendly? And how do we get people to the right content faster?”

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          The answer is an intentional mix of design, organization, and style. “I think the root of our success from the very beginning was creating a warm feel and brand,” he says.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          Headspace is easy to navigate, and its collections and activities are clearly labeled.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          It’s hardly an overstatement to say that Headspace has been part of a tremendous social change regarding mental health. Birkeland says the app has been used by more than 100 million people in nearly 200 countries and regions, and it’s easy to see why. Headspace is an incredibly versatile tool for anyone looking for a quick clarity break, longer guided sessions, or help with sleep or exercise. And its huge library of resources is there whenever people need it.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          Jeff Birkeland, Headspace

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          Headspace smartly organizes its library of resources through language. Collections and exercises are labeled with understandable purposes, like Unlocking Creativity, Mindful Eating, and The Shine Collection, a set of activities drawn from Headspace’s recent merger with Shine, a mindfulness app dedicated to providing inclusive and accessible mental health resources that support marginalized communities. “It’s still a simple app,” Birkeland says, “but it’s not a very long trip into an extensive archive.”

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          How do we make [mindfulness and mental health] approachable and friendly? And how do we get people to the right content faster?

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          Jeff Birkeland, Headspace senior vice president for member products

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          In previous versions of Headspace, the core navigation included tabs for meditation, focus, movement, and sleep. But Birkeland says user research convinced the team to strip away that complexity and focus instead on the app’s Today tab, which facilitates one-tap access to activities of varying lengths for morning, afternoon, and night. Importantly, it does so without bringing up specific categories.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          Headspace’s illustration style and color scheme are part of the app’s mission to feel warm and friendly.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          The Explore tab, meanwhile, is the gateway to that vast bank of content — including those former category-based parts of the core navigation. “There’s still simplicity at the surface,” says Birkeland. “But there’s an incredible depth of content underneath.” This tab is also where people find collections and activities of all kinds, including those with titles like Cultivating Black Joy and Navigating Injustice that illustrate Headspace’s commitment to representation.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          “Mindfulness, meditation, mental health — none of these are easy to navigate,” Birkeland says. “An app that feels warm, friendly, and easy to use can provide approachable support for tough issues.”

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          Learn more about Headspace

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          Download Headspace from the App Store

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          Behind the Design is a series that explores design practices and philosophies from each of the winners of the Apple Design Awards. In each story, we go behind the screens with the developers and designers of these award-winning apps and games to discover how they brought their remarkable creations to life.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          Explore more of the 2023 Behind the Design series

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          Behind the Design: Any Distance

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            Workout tracking has never looked — or felt — like it does in Any Distance.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            “We’re building something for everyone, not just athletes,” says Luke Beard, the Atlanta-based designer who created this Swift app with engineer Daniel Kuntz. “We’re not athletically inclined people. We’re kind of dorks! I want to retire and take photos in Iceland one day. Dan wants to retire and play music in the desert. We’re not looking to go to the Olympics, but we do want to live long, healthy lives.”

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            Any Distance presents its workout stats in a variety of eye-popping formats.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            Their app is a design-forward fitness tracker and social network that delivers workout stats in beautiful and shareable formats — dynamic charts and graphs, animated 3D maps, AR experiences, and gorgeous cards — that can integrate photos. It draws heavily on SF Symbols — as Beard cheekily puts it, “SF Symbols is the single greatest contribution to design Apple has ever made.” It offers elegant in-app collectibles and an in-house social network aimed at connecting people with a small circle of friends. And its name is also its philosophy: Any Distance counts, not just a swim or bike ride, but a walking meeting, stroller run, or its most popular option, a dog walk.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            Luke Beard, Any Distance

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            Any Distance is heavily powered by Apple tools and technologies. It uses ARKit for rendering routes, HealthKit for workout data, Metal rendering for what Kuntz calls the “gradient background swirly thing,” SceneKit for rendering, MapKit, Apple Watch integration, and more. It also demonstrates Any Distance's commitment to privacy. "Your data is all in HealthKit; we don’t store it unless you post it to your friends,” Beard says. “We don’t let you share a map. Route clipping (in which the beginning and end of your routes are trimmed from public view) is on by default.” And people can choose exactly what data they want to share with friends by simply tapping the eye icon under each metric.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            SF Symbols is the single greatest contribution to design Apple has ever made.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            Luke Beard, Any Distance founder

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            Beard conceived of the idea for Any Distance during the pandemic, when his lifestyle wasn’t quite as healthy as he would have liked. To shake himself out of his funk, he began going on long walks, posting photos of his journeys along the way. “I’m a chronic oversharer,” laughs Beard, “and a photographer at heart. And I was getting good feedback.” Eventually, he started designing templates for his social media posts. “Honestly, it was just a photo in a mask — the oval that’s now one of our main brand characteristics — with the route and stats in a fun font. But people would ask, ‘What app is making those?’”

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            Just a few of the spiffy medals you can earn by sharing workouts in Any Distance.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            By this point, he’d already connected with Daniel Kuntz, a programmer and musician who already had a few titles on the App Store. “As a developer, I’m often asked, ‘Hey, can you make this app?’ And I’m always like, ‘Nah,’” says Kuntz. “In this case, Luke had it all fleshed out. He had iOS components and a Sketch file. It was simple and clear and really cool.”

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            This year, the team also plans to add more unorthodox activity options like trick-or-treating. “Eventually we want to organize group bike rides or group dog walks,” says Beard. “The last few years have accelerated the loneliness epidemic so much, and we think working out or being active together is the new hanging out. It doesn’t matter if you’re walking half a mile, taking a stroller walk with your kid, or walking with a cane — there should be a space for you.”

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            Download Any Distance from the App Store

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            Behind the Design is a series that explores design practices and philosophies from each of the winners of the Apple Design Awards. In each story, we go behind the screens with the developers and designers of these award-winning apps and games to discover how they brought their remarkable creations to life.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            Explore more of the 2023 Behind the Design series

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            Apple Design Award winners announced

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              The Apple Design Awards celebrate apps and games that excel in the categories of Inclusivity, Delight and Fun, Interaction, Social Impact, Visuals and Graphics, and Innovation. Learn about the 2023 winning apps and the talented developers behind them.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              Discover the winners

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              Behind the Design: stitch.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                For all its many genres and styles, the gaming world has been awfully threadbare when it comes to experiences about embroidery. That all changes with stitch., a charming cross between casual puzzler, meditative exercise, and afternoon craft project — and as cross-generational a game as you’re likely to find.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                “We pride ourselves on making games that anyone can play,” says Jakob Lykkegaard, founder of Lykke Studios, the team behind stitch. “It’s important to spend the time to make them available for everyone.”

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                In stitch., players solve number puzzles to fill out embroidery patterns — sometimes very cute ones.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                stitch. sets up embroidery-based puzzles that players complete to finish a pattern, like an adorable penguin or a love note to bacon. Players swipe over an incredibly lifelike and beautifully textured surface that feels like it’s just beneath the display. There’s no linear progression in stitch.; challenges are presented in the form of “hoops” that players can explore at their own pace. And the game supports multiple languages and custom accessibility tools for people with color blindness, low vision, and motion sensitivities.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                There’s precedent for those choices. Lykke Studios’ painting puzzler tint. was nominated for a 2022 Apple Design Award in the Inclusivity category, thanks in part to a colorblind mode that lets players solve each watercolor-based puzzle by using patterns and texture instead of color.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                Jakob Lykkegaard, stitch.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                With stitch., which was built with Unity, the studio explored accessibility features even further. “Number Outlines” creates sharper and more contrasting outlines on the puzzles’ numbers. “Big Numbers” makes them larger and easier to read. “Reduce Motion” limits sudden movements and animations. And the left-handed mode shifts problematic UI out of the way for left-handed players. Lykkegaard says, “Originally, the icon indicator was actually under the hand for left-handed people. We thought, ‘That’s an issue we hadn’t considered. How can we fix it?’”

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                We pride ourselves on making games that anyone can play.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                Jakob Lykkegaard, founder of Lykke Studios

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                Lykkegaard says the team took an unusual approach to sewing up the idea for stitch. “We build games a little bit upside down,” he says. “It usually starts with us falling in love with some material and building a game mechanic around it later. We’ll see how it feels on device and, if it’s not working, we’ll kill the project and move on to another material.” For stitch., that material came from a serendipitous day on social media. “We honestly just saw a post about embroidery and thought, ‘Wow, that looks really nice.’”

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                The stitch. team created real-life test hoops as inspiration for the ones in the game.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                For that mechanic, the team found inspiration in an unlikely analog source: a geometric grid-based puzzle game called Shikaku found in Japanese newspapers. “We took the grid and skewed it into something that looks nice but isn’t uniform,” he says. “From there, we had a lot of options for how players could fill it out.”

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                As with tint., the team looked to strike a balance that would challenge players without making them feel lost or intimidated. “We didn’t want to make a game like sudoku where people thought, ‘Oh, that’s too difficult for me.’ But we also didn’t want something that was just an endless series of careless clicks. stitch. couldn’t be too hard for kids, but it couldn’t be too childish either.”

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                It’s working. Lykkegaard has heard from 8-year-olds and 80-year-olds who’ve been drawn to the game’s approachable, accessible style. “The question is: How can we get a player to enjoy it, feel smart, and want to relax with the game? Once you’ve generated that feeling, players will come back. And we want to make everyone feel like this is a game for them.”

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                Learn more about stitch.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                stitch.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                Behind the Design is a series that explores design practices and philosophies from each of the winners of the Apple Design Awards. In each story, we go behind the screens with the developers and designers of these award-winning apps and games to discover how they brought their remarkable creations to life.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                Explore more of the 2023 Behind the Design series

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                Behind the Design: Flighty

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  Flighty might be the easiest thing travelers navigate on their entire trip. “Travel can be a high-stress situation,” says Ryan Jones, the Austin-based developer who founded the app in 2019. “We want Flighty to work so well that it feels almost boringly obvious.”

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  Conceived during — when else? — a long flight delay, Flighty puts key information front and center with an immediately understandable interface, live maps, and a look that mirrors time-honored airport design conventions. The best-in-class travel app is a flight tracker, airport navigator, and concierge — and with incredible implementations of Live Activities and the Dynamic Island, a companion that makes key information available at all times.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  Flighty puts key information front and center at all times — especially through its best-in-class Live Activities.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  “There’s something comforting about information always being there,” Jones says. “You don’t have to check your phone and think, ‘OK, I have to be at the gate in 32 minutes,’ and then, ‘Now I have to be there in 29 minutes.’ And I don’t know about you, but every time I walk on a plane, I look at my seat number, put it down, and immediately say, ‘Wait, what was my seat number?’”

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  Since its 2019 launch, Flighty has been an incredible example of the carefully crafted use of Apple technologies. “We’re really doing this out of a passion and love for the product,” says Jones, “We all had our lives changed by iOS and mobile, so we get really excited about adopting new technologies.”

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  Ryan Jones, Flighty

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  They’ve added a lot. Flighty supports widgets on the Home Screen and Lock Screen, highlighting content using Shared with You, and more. With a few taps, travelers can even live-share their flight path and arrival time with loved ones who may not even have the app installed — a wonderfully convenient feature for coordinating airport pickups.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  We want Flighty to work so well that it feels almost boringly obvious.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  Ryan Jones, Flighty founder

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  Flighty is consistently impressive in adjusting to the unpredictable nature of travel. “We really have to shine when things go awry,” says Jones. For instance, the app must account for how every single person will, at some point, lose their internet connection. “Whenever [someone] takes off, we have to assume that we won’t see them again until they land,” says Jones. The solve? At a certain point before a flight takes off, the Dynamic Island switches over to flight progress bars and counters, displaying minimal presentation in a simple circular chart that tracks a flight’s duration.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  The Flighty Passport features shows your flights, miles, and travel stats, and the Friends' Flights screen is a convenient way to keep up with others.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  Visually, both Live Activities and the Dynamic Island are designed to recall airport signage conventions that have been in place for decades. “That’s our real-world analogy,” Jones says. “Those airport boards have one line per flight, and that’s a good guiding light — they’ve had 50 years of figuring out what’s important.”

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  While the design process is comprehensive, it’s not always fast. “It’s so tempting to start pulling from your existing asset library to see if you can quickly put something together,” he says. To avoid falling back on old ideas, the Flighty team creates 20 design ideas during the concept phase. “It’s what fits on a sheet of paper,” he says with a smile. “You get to six or seven ideas and think, ‘OK, that’s it, there’s none left.’ But then you think, ‘Well, I have an idea that will probably look bad,’ and then you try it and it’s not bad at all.”

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  Flighty is even fun at home. The Flighty Passport feature shows flights, miles, and travel stats through gorgeous, shareable custom artwork. It’s just more proof that Flighty really is for every step of the journey — even being back home.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  Learn more about Flighty

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  Download Flighty from the App Store

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  Behind the Design is a series that explores design practices and philosophies from each of the winners of the Apple Design Awards. In each story, we go behind the screens with the developers and designers of these award-winning apps and games to discover how they brought their remarkable creations to life.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  Explore more of the 2023 Behind the Design series

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  Behind the Design: Resident Evil Village

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    Evil has never looked better than it does in Resident Evil Village.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    The AAA horror adventure is a masterpiece of visual detail on Mac, a feast of creepy castles, decrepit factories, and majestically gothic villains. The game’s bleak village is thick with details and dread; characters like Lady Dimitrescu and the game’s army of mutant lycans nearly pop out of the screen. Simply put, Resident Evil Village contains some of the most realistic graphics ever seen on Apple hardware. And the lavish visuals don’t just look amazing; they drag players into the game’s horrifying landscape and through dark mysteries, vicious confrontations, and mind-blowing plot twists.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    Resident Evil Village makes desolation look incredible.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    It’s all powered by a remarkable assembly of cutting-edge Apple technologies. Resident Evil Village takes full advantage of Apple silicon, ProMotion, Metal 3, and extended dynamic range to serve up its breathtaking visual achievements. “The game is very pretty, but it has this incredible sense of fear,” says Tsuyoshi Kanda, one of the game’s producers. “In some of the first scenes, you end up battling this horde of lycans. The sheer amount of them is impressive. But each has its own intention and personality. We’re happy with how it turned out.”

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    Those achievements are especially clear in the game’s village, which feels like a character in itself. The village shines in its decay; it’s a showcase of textures, geometry, and complex shaders. And players can enable MetalFX Upscaling to make it look especially breathtaking. Kazuki Kawato from the game’s engine team says the game benefits from both spatial and temporal upscaling. “Both were easy to use and gave us the results we wanted,” he says.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    Tsuyoshi Kanda, Resident Evil Village

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    Masaru Ijuin, senior manager in the engine development team, says he always knew the game was beautiful. “Our main focus was taking the base game and making it run as fast and as stable as possible on Mac,” he says, “and I think we did that.”

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    Kanda calls out the Castle Dimitrescu, home of the game’s breakout villain, the 9-foot-tall vampire giantess Lady Dimitrescu. “The castle looks incredible no matter where you are,” he says. “There’s an entrance hall with a chandelier inside that we’re all really proud of. The team worked hard to create the best graphics possible on the hardware.”

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    The game’s visuals are deserving of acclaim, but Resident Evil Village also boasts an incredible story and character design. It’s a masterclass in horror pacing that skillfully mixes bursts of frantic action with long stretches of good old dread-building. Kanda says the team paid special attention to creating what he proudly calls a “variety of horrific entertainment.”

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    Lycans are on the move in this piece of early Resident Evil Village concept art.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    “The concept is a horror theme park with characters that stand out against this beautifully rendered environment,” he says. “The stages cycle between horror and action to help players stay balanced. That’s something we learned from other Resident Evil games.”

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    Balance was also key in creating the game’s story, which had to fit into the Resident Evil universe (Village is the eighth major game in the series) while taking the storyline in wild new directions. “One of the base concepts was Ethan Winters at home with his wife and baby daughter, Rose,” says Kanda. “You see Ethan’s fatherly love all throughout the game.”

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    The concept is a horror theme park, with characters that stand out against this beautifully rendered environment.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    Tsuyoshi Kanda, Resident Evil Village producer

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    But in the game’s intro, Rose is kidnapped from the family home in a shocking confrontation with Chris Redfield, a character who’s been around since the first Resident Evil. “Chris was such a big part of world-building this; the way he enters the game was so important,” says Kanda. “We didn’t want you to know his intentions until the ending.”

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    To get to that ending — which is as dramatic as Kanda promises — players must battle through a murderer’s row of memorable villains that look alive, even if they’re (probably?) not. There’s Salvatore Moreau, a hideous mutant; Karl Heisenberg, who runs a factory with some serious health-code violations; Donna Beneviento and her scary doll, which is probably all we need to say about that; and Lady Dimitrescu, the superstar with huge claws, a deathly gothic wardrobe, and a surprisingly devoted fan base.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    The game’s myriad monsters look incredible (both inside and outside).

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    “The idea for Lady Dimitrescu was a huge character who was too big for the castle itself,” says Kanda. “She has to duck to get through the doors. And when she comes at you, you really feel her presence.”

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    As an incredible example of Mac gaming, Resident Evil makes its presence felt too. But this story has a twist ending of its own: Kanda, Ijuin, and Kawato personally aren’t all that into horror. “The (Resident Evil) creative team loves horror movies,” laughs Kanda, “but I’m more into the not-too-scary stuff.”

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    Learn more about Resident Evil Village

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    Download Resident Evil Village from the Mac App Store

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    Behind the Design is a series that explores design practices and philosophies from each of the winners of the Apple Design Awards. In each story, we go behind the screens with the developers and designers of these award-winning apps and games to discover how they brought their remarkable creations to life.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    Explore more of the 2023 Behind the Design series

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    Behind the Design: Railbound

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      For a creative guy, Luke Spierewka, founder of the Poland-based game studio Afterburn, is certainly a fan of limitations.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      “We make comfy puzzle games that convey an idea quickly,” he says, “but they’re all about using a limited amount of something, which is where the challenge comes in.”

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      Railbound’s track-laying mechanic is as simple as finger painting.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      In Afterburn’s Railbound, players are challenged to link train cars in proper order by laying down track, manipulating switches, and navigating an increasingly convoluted series of gates, tunnels, and stations. While the puzzles may be tricky, interacting with them is sheer joy. The track-laying mechanic is as simple as finger painting, mistakes can be easily undone, and the game is full of thoughtful details, like its duo of canine conductors or the squiggly frustration cloud that appears over a misdirected train car. And it’s all presented in a bright cartoon style inspired by European comics.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      Luke Spierewka, Railbound

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      Railbound’s interaction design is the product of Spierewka’s drive to make his studio’s games ever easier to play. “I pay a lot of attention to input. For Railbound, I wanted a system where you basically paint rail tiles with one finger,” he says. “I knew if we didn’t make that mechanic fun and malleable, people would be much less inclined to play. And I think we got there,” he says, before pausing and adding, “but I’m still thinking about how to make it more intuitive.”

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      The studio, which Spierewka runs with his wife, Kamila, also paid close attention to the size of the puzzles. “In games like Stephen’s Sausage Roll or A Monster’s Expedition, the size of the level is exactly what you need to solve it. I’m not gonna pretend we’re as elegant as those, but I try to constrain our puzzles and space as much as I can, and leave only the stuff you need.”

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      Railbound’s cute characters add to the game’s bright cartoon style.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      That strategy also applies to the game’s onboarding, a process that’s largely wordless because of the unsubtle lessons the Afterburn team learned on previous games. “The first version of [our earlier game] Golf Peaks had all this onboarding text,” he says. “The first level introduced five different concepts. The second level was like, ‘This is a new tile type, deal with it.’ The third level was like, ‘Here’s another new type, deal with that too,’” he laughs. “And nobody read them! Every single person I handed a phone to tapped right past the blocks of onboarding text. It was kind of a shock, really.”

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      Nobody read them! Every single person I handed a phone to tapped right past the blocks of onboarding text. It was kind of a shock, really.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      Luke Spierewka, Afterburn

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      For Railbound, Spierewka jettisoned words entirely. “We thought, ‘What is the simplest way we can break down and teach mechanics?’” The answer was to integrate them into early gameplay. Railbound’s first level gives players just one way to place a track; it’s actually impossible not to beat. In levels 1 through 3, you learn to bend and rotate tiles. “You’re not even taught how to delete tiles until several levels in, because you don’t need to yet. It’s all a dance of introducing and reinforcing concepts at the right pace.” In other words, even the onboarding is an example of using only the stuff you need.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      Learn more about Railbound

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      Download Railbound from the App Store

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      Behind the Design is a series that explores design practices and philosophies from each of the winners of the Apple Design Awards. In each story, we go behind the screens with the developers and designers of these award-winning apps and games to discover how they brought their remarkable creations to life.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      Explore more of the 2023 Behind the Design series

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      Behind the Design: Endling

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        Endling is all about survival in a changed world — and it’s a powerful mix of medium and message.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        The game is a gorgeous adventure in which you play as a fox navigating a land charred by environmental disaster and human impact. Endling is not subtle — particularly when the fox starts defending its tiny offspring from an ever-increasing array of man-made dangers. Still, it draws players in with beautiful visuals, lush animations, a moody soundtrack, and brilliantly intuitive gameplay.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        “It’s a survival game, but a simplified one that focuses more on telling a story,” says Philipp Nägelsbach, game designer and producer at HandyGames.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        In Endling, you play as a lone fox navigating a land charred by human impact.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        When creating such a game, balance is paramount. “You need to have cute scenes with the foxes safe in their lair, learning and growing,” says Nägelsbach. “And you have to have dramatic scenes to illustrate the real dangers.”

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        After an onboarding process that drops players into the heat of the action, the game becomes an open-world adventure that rewards exploration. That wasn’t always the case; Nägelsbach notes that the game’s earliest versions had a more linear structure. “It didn’t suit the message as well,” he says. “It’s much easier to show the ecological impact humans have when you visit the same spot several times and see a river that’s full of trash or a forest that’s been cut down.”

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        Philipp Nägelsbach, HandyGames

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        To control the fox, players operate a simple one-thumb control on the lower-left corner of the screen. The game gradually introduces additional interactions, like the ability to climb or jump over an obstacle. “That’s the moment people realize this isn’t entirely a side-scroller,” says Nägelsbach.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        And then there’s the fox itself. Endling casts players as the animal in distress to create an instant sense of empathy — and their choice of animal was well-considered. "Foxes are some of the most adaptable animals in the world,” says Nägelsbach. “They’re not the biggest or smallest; they’re in the middle of the food chain. But if they’re close to extinction, things are really bad.”

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        It’s a survival game, but a simplified one that focuses more on telling a story.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        Philipp Nägelsbach, game designer and producer at HandyGames

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        Doing so required numerous design considerations. The fox needed to be adorable enough to engage with, realistic enough to feel authentic, and believable enough to navigate the apocalyptic landscape. The fox doesn’t realize what’s happening to the environment; only the player recognizes the meaning of factories, careening trucks, and men in hazmat suits. “And the fox can only do things real foxes can do,” says Naegelsbach. “We couldn’t have the fox pushing buttons or solving complex puzzles.”

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        As the game progresses, you’re charged with protecting your tiny offspring from man-made dangers.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        Extra attention was paid to the fox’s kits, who grow and develop unique personalities as the game goes on. Each kit represents a player’s life and has an instrument attached to it; when players lose kits, the game feels quieter and more lonely.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        Nägelsbach says the teams did make adjustments to ensure the game wasn’t too severe, including the ability to replay parts of the story after a loss instead of starting over. The kits have only one owl enemy; they can’t be directly hurt by humans or dogs. And the fox’s cute bark is a mix of several different animal sounds. “In the real world, foxes aren’t very pleasant to listen to,” says Nägelsbach, “and you shouldn’t be annoyed by your protagonist.”

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        Endling ultimately delivers a message that sticks around long after gameplay ends. "The message is harsh,” says QA lead and producer Jan Pytlik, “but the game didn’t need to be harsh too. We worked and fine-tuned and I think we hit the mark.”

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        Learn more about Endling

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        Endling

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        Behind the Design is a series that explores design practices and philosophies from each of the winners of the Apple Design Awards. In each story, we go behind the screens with the developers and designers of these award-winning apps and games to discover how they brought their remarkable creations to life.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        Explore more of the 2023 Behind the Design series

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        Spotlight on: Developing for visionOS

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          What’s it like to develop for visionOS? For Karim Morsy, CEO and co-founder of Algoriddim, “it was like bringing together all of the work we've built over many years.”

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          Algoriddim’s Apple Design Award-winning app djay has long pioneered new ways for music lovers and professional DJs alike to mix songs on Apple platforms; in 2020, the team even used hand pose detection features to create an early form of spatial gesture control on iPad. On Apple Vision Pro, they’ve been able to fully embrace spatial input, creating a version of djay controlled entirely by eyes and hands.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          “I've been DJing for over twenty years, in all sorts of places and with all sorts of technology, but this frankly just blew my mind,” says Morsy. "It's a very natural way to interact with music, and the more we can embrace input devices that allow you to free yourself from all these buttons and knobs and fiddly things — we really feel it's liberating.”

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          “It’s emotional — it feels real.”

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          It’s a sentiment shared by Ryan McLeod, creator of Apple Design Award-winning puzzle game Blackbox. “You have a moment of realizing — it's not even that interacting this way has become natural. There is nothing to ‘become natural’ about it. It just is!” he says. “I very vividly remember laughing at that, because I just had to stop for a moment and appreciate it — you completely forget that this [concept] is wild.”

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          Blackbox is famous on iOS for “breaking the fourth glass wall,” as McLeod puts it, using the sensors and inputs on iPhone in unusual ways to create dastardly challenges that ask you to do almost everything but touch the screen. Before bringing this experience to visionOS, however, McLeod had his own puzzle to solve: how to reimagine the game to take advantage of the infinite canvas offered by Vision Pro.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          “You really have to go back to those first principles: What will feel native and natural on visionOS, and within a person’s world?” he says. “What will people expect — and what won’t they? How can you exist comfortably like that, and then tweak their expectations to create a puzzle, surprise, and satisfaction?”

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          After some early prototyping of spatial challenges, audio quickly became a core part of the Blackbox story. While McLeod and sound designer Gus Callahan had previously created sonic interfaces for the iOS app, Spatial Audio is bringing a new dimensionality to their puzzles in visionOS. “It’s a very fun, ineffable thing and completely changes the level of immersion,” he says. “Having sounds move past you is a wild effect because it evokes emotion — it feels real.”

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          “It will take you minutes to have your own stuff working in space.”

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          As someone who had exclusively developed for iOS and iPadOS for almost a decade — and had little experience with either 3D modeling or RealityKit — McLeod was initially trepidatious about trying to build an app for spatial computing. “I really hadn’t done a platform switch like that,” he says. But once he got started in Xcode, “there was a wild, powerful moment of recognizing how to set this up.”

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          visionOS is built to support familiar frameworks, like SwiftUI, UIKit, RealityKit, and ARKit, which helps apps like Blackbox bring over a lot of their existing codebase without having to rewrite from scratch. “What gets me excited to tell other developers is just — you can make apps really easily,” says McLeod. “It will take you minutes to have your own stuff working in space.”

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          Even for developers working with a more complex assortment of frameworks, like the team behind augmented reality app JigSpace, the story is a similar one. “Within three days, we had something up and running,” says CEO and co-founder Zac Duff, crediting the prowess of his team for their quick prototype.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          One member of that team is JigSpace co-founder Numa Bertron, who spent a few days early in their development process getting to know SwiftUI. “He’d just be out there, learning everything he could, playing with Swift Playgrounds, and then he’d come back the next day and go: ‘Oh, boy, you won’t believe how powerful this thing is,’” Duff says.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          Though new to SwiftUI, the JigSpace team is no stranger to Apple’s augmented reality framework, having used it for years in their apps to help people learn about the world using 3D objects. On Vision Pro, the team is taking advantage of ARKit features to place 3D objects into the world and build custom gestures for scaling — all while keeping the app’s main interface in a window and easily accessible.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          JigSpace is also exploring how people can work together with SharePlay and Spatial Personas. “It's a fundamental rethink of how people interact together around knowledge,” says Duff. “Now, we can just have you experience something right in front of you. And not only that — you can bring other people into that experience, and it becomes much more about having all the right people in the room with you.”

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          “You want to feel at home.”

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          Shared experiences can be great for education and collaboration, but for Xavi H. Oromí, chief engineering officer at XRHealth, it’s also about finding new and powerful ways to help people. While Oromí and his team are new to Apple platforms, they have significant expertise building fully immersive experiences: They were creating apps for VR headsets as early as 2012 in order to assist people in recognizing phobias, physical rehabilitation, mental health, and other therapy services.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          Vision Pro immediately clicked for Oromí and the team, especially the fluidity of immersion that visionOS provides. “Offering some sort of gradual exposure and letting the person decide what that should look like — it’s something that’s naturally very integrated with therapy itself,” says Oromí.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          With that principle as their bedrock, the team designed an experience to help people with acrophobia (fear of heights), built entirely with Apple frameworks. Despite having no prior development experience with Swift or Xcode, the team was able to build a prototype they were proud of in just a month.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          In their visionOS app, a person can open a portal in their current space that gives them the feeling of being positioned at a significant height without fully immersing themselves in that app’s environment. For Oromí, this opens up new possibilities to connect with patients and help them feel grounded without overtaxing their comfort level. “You want to feel at home,” says Oromí, “The alternative before [in a completely immersive experience] was that I needed to remove the headset, and then I totally broke the immersion.”

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          It also has the added benefit of giving people a way to stay true to themselves. In some of their previous immersive experiences on other platforms, Oromí notes, patients’ hands and bodies were represented in the space using virtual avatars. But this had its own challenges: “We had a lot of patients saying that they felt their body was not theirs,” he says. “It’s very difficult for our society that’s so diverse to create representations of avatars that match everyone in the world... [In Vision Pro], where you can see your own body through the passthrough, we don’t need to create a representation.”

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          When combined with SharePlay, people can stay connected and supported with their virtual therapists while pushing their boundaries and challenging common fears. “Years from now, when we look back,” Oromí says, “we will be able to say it all started with the launch of Vision Pro — it’s where we truly enabled real virtual therapy.”

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          “You’re off to the races.”

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          When the SDK arrives later this month, developers worldwide will be able to download Xcode and start building their own apps and games for visionOS. With 46 sessions focused on Apple Vision Pro premiering at WWDC, there’s a lot of new knowledge to explore — but Duff and McLeod have a few supplemental recommendations.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          “Pick up SwiftUI if you haven't yet,” says McLeod, noting that getting to know the framework can help developers add core platform functionality to their existing app. He also suggests getting comfortable with basic modeling and Reality Composer Pro. “At some point, you're gonna want to come off the page,” he says. But, he notes with a smile, you don't need to become a 3D graphics expert to build for this platform. "You can get really far with a simple model and [Reality Composer Pro] shaders."

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          Duff mirrors these recommendations, adding one last framework to the list: RealityKit. “If you’re transitioning from [other renderers] there are some fundamental changes you have to get to know,” he says. “But with those three things, you’re off to the races.”

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          Learn more about developing for visionOS and what you can do to get ready for the SDK on developer.apple.com.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          Learn more about developing for visionOS

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          Prepare your apps for visionOS

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          Explore sessions about visionOS

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          Meet visionOS

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            Get ready to design and build an entirely new universe of apps and games for Apple Vision Pro. Find out how developers of apps like djay, Blackbox, JigSpace, and XRHealth are starting to build for spatial computing.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            We'll show you how you can prepare for the visionOS SDK, help you learn about best-in-class frameworks and tools, and explore programs and events to help support you along your development journey.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            Spotlight on: Developing for visionOS View now

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            Learn more about developing for visionOS

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            Prepare your apps for visionOS

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            Explore sessions about visionOS

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            Find out what’s new for Apple developers

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              Discover the latest advancements on all Apple platforms. With an incredible new opportunity in spatial computing in visionOS, new features in iOS, iPadOS, macOS, tvOS, and watchOS, and major enhancements across languages, frameworks, tools and services, you can create even more unique experiences for users worldwide.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              Learn what’s new

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              Introducing Apple Vision Pro and visionOS

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                Apple Vision Pro is a revolutionary spatial computer that seamlessly blends digital content with the physical world, while allowing users to stay present and connected to others. Apple Vision Pro creates an infinite canvas for apps that scales beyond the boundaries of a traditional display and introduces a fully three-dimensional user interface controlled by the most natural and intuitive inputs possible — a user’s eyes, hands, and voice. Featuring visionOS, the world’s first spatial operating system, Apple Vision Pro lets users interact with digital content in a way that feels like it is physically present in their space. The breakthrough design of Apple Vision Pro features an ultra-high-resolution display system that packs 23 million pixels across two displays, and custom Apple silicon in a unique dual-chip design to ensure every experience feels like it’s taking place in front of the user’s eyes in real time.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                Discover the resources you can use to bring your spatial computing creations to life with a new, yet familiar, way to build apps that reimagine what it means to be connected, productive, and entertained.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                Learn more about visionOS

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                Updated agreements and guidelines now available

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  The App Store Review Guidelines, the Apple Developer Program License Agreement, and the Apple Developer Agreement have been updated to support updated policies and upcoming features, and to provide clarification. Please review the changes below and accept the updated terms as needed.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  App Store Review Guidelines
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  • Added to 2.5.18: “Apps that contain ads must also include the ability for users to report any inappropriate or age-inappropriate ads.”
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  • Revised bullet point 11 of 3.1.2(a): “Cellular carrier apps may include auto-renewing music and video subscriptions when purchased in bundles with new cellular data plans, with prior approval by Apple. Other auto-renewing subscriptions may also be included in bundles when purchased with new cellular data plans, with prior approval by Apple, if the cellular carrier apps support in-app purchase for users. Such subscriptions cannot include access to or discounts on consumable items, and the subscriptions must terminate coincident with the cellular data plan.”
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  • Added to 4.1: “Submitting apps which impersonate other apps or services is considered a violation of the Developer Code of Conduct and may result in removal from the Apple Developer Program.”
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  • Revised 4.4: “Apps hosting or containing extensions must comply with the App Extension Programming Guide, the Safari App Extensions Guide, or the Safari Web Extensions documentation and should include some functionality, such as help screens and settings interfaces where possible.”
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  • Revised 4.4.2: “Safari extensions must run on the current version of Safari on the relevant Apple operating system.”
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  Developer Program License Agreement
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  • Purpose; Definitions; Sections 2.6, 3.2, 3.3.4, 3.3.38, 3.3.63, 5.1, 6.3, 6.6, 7, 7.3, 7.5, 7.6, 14.2; Attachment 7: Specified requirements and functionality for apps on visionOS.
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  • Definitions: Updated requirements for Corresponding Products.
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  • Definitions; Section 3.1: Specified requirements for universities and their Authorized Student Developers.
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  • Definitions; Section 3.3.62: Specified requirements for use of the Tap to Present ID API.
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  • Definitions; Sections 3.3.40, 3.3.64, 5.1, 10; Attachment 10: Specified requirements for use of mobile device management (MDM).
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  • Definitions; Section 3.3.65: Specified requirements for use of the iWork Document Exporting API.
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  • Definitions; Section 3.3.67: Specified requirements for use of the Sensitive Content Analysis Framework.
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  • Definitions; Attachment 3: Updated requirements for development of Passes.
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  • Section 3.3.9: Added requirements for use of third-party SDKs and certain APIs, clarified restrictions on use of data derived from a device.
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  • Section 3.3.42: Added requirements for use of certain Apple Pay APIs.
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  • Section 3.3.63: Specified requirements for providing a partially immersive experience in an app.
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  • Section 3.3.66: Specified requirements for the use of the Shallow Depth and Pressure feature.
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  • Section 6.7: Added information on App Analytics.
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  • Attachment 2: Clarified requirements for use of the In-App Purchase API.
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  Apple Developer Agreement
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  • Sections 4, 6: Updated requirements for access to and use of pre-release materials.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  View agreements and guidelines

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  What’s new in privacy on the App Store

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    At Apple, we believe privacy is a fundamental human right. That is why we’ve built a number of features to help users understand developers’ privacy and data collection and sharing practices, and put users in the driver’s seat when it comes to their data. App Tracking Transparency (ATT) empowers users to choose whether an app has permission to track their activity across other companies’ apps and websites for the purposes of advertising or sharing with data brokers. With Privacy Nutrition Labels and App Privacy Report, users can see what data an app collects and how it’s used.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    Many apps leverage third-party software development kits (SDKs), which can offer great functionality but may have implications on how the apps handle user data. To make it even easier for developers to create great apps while informing users and respecting their choices about how their data is used, we’re introducing two new features.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    First, to help developers understand how third-party SDKs use data, we’re introducing new privacy manifests — files that outline the privacy practices of the third-party code in an app, in a single standard format. When developers prepare to distribute their app, Xcode will combine the privacy manifests across all the third-party SDKs that a developer is using into a single, easy-to-use report. With one comprehensive report that summarizes all the third-party SDKs found in an app, it will be even easier for developers to create more accurate Privacy Nutrition Labels.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    Additionally, to offer additional privacy protection for users, apps referencing APIs that could potentially be used for fingerprinting — a practice that is prohibited on the App Store — will now be required to select an allowed reason for usage of the API and declare that usage in the privacy manifest. As part of this process, apps must accurately describe their usage of these APIs, and may only use the APIs for the reasons described in their privacy manifest.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    Second, we want to help developers improve the integrity of their software supply chain. When using third-party SDKs, it can be hard for developers to know the code that they downloaded was written by the developer that they expect. To address that, we’re introducing signatures for SDKs so that when a developer adopts a new version of a third-party SDK in their app, Xcode will validate that it was signed by the same developer. Developers and users alike will benefit from this feature.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    We’ll publish additional information later this year, including:

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    • A list of privacy-impacting SDKs (third-party SDKs that have particularly high impact on user privacy)
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    • A list of “required reason” APIs for which an allowed reason must be declared
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    • A developer feedback form to suggest new reasons for calling covered APIs
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    • Additional documentation on the benefits of and details about signatures, privacy manifests, and when they will be required

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    WWDC23 Overview

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      Join us for an exhilarating week of technology and community. Be among the first to learn the latest about Apple platforms, technologies, and tools. You’ll also have the opportunity to engage with Apple experts and other developers. All online and at no cost.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      Experience WWDC here and on the Apple Developer website.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      Keynote and State of the Union

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      The Apple Worldwide Developers Conference kicks off with exciting reveals and new opportunities. Join the developer community for an in-depth look at the future of Apple platforms, directly from Apple Park.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      Keynote Watch now Platforms State of the Union Watch now Apple Design Awards

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      The Apple Design Awards celebrate apps and games that excel in the categories of Inclusivity, Delight and Fun, Interaction, Social Impact, Visuals and Graphics, and Innovation. Join us in congratulating this year’s finalists and winners.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      June 5, 6:30 p.m. PT.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      Explore the winners

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      Sessions

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      Learn how to create your most innovative apps and games yet by taking advantage of the latest updates on Apple platforms. New videos and transcripts will be posted daily from June 6 through 9. Watch on the web or in the Apple Developer app for iPhone, iPad, Mac, and Apple TV.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      Learn more

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      Labs

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      Get one-on-one guidance from Apple engineers, designers, and other experts. Learn how to implement new Apple technologies, explore UI design principles, improve your App Store presence, and much more.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      Learn more

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      Activities

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      Join Apple engineers, designers, and other experts for Q&As, Meet the Presenter, icebreakers, and more.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      Learn more

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      Sign up

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      Forums

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      Connect with the community on the Apple Developer Forums. Find WWDC23 content quickly and easily by searching conference-specific tags.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      Learn more

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      Beyond WWDC

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      Discover even more opportunities for learning, networking, and fun outside of the conference.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      Learn more

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      Stay connected

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      We’ll be posting WWDC announcements leading up to and during the conference.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      Check your email settings in your Apple Developer account. Check your notification settings in the Account tab.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      Watching session videos, viewing related documentation and sample code, and posting on the forums are available to anyone. To request a lab appointment or sign up for activities, you must be a current member of the Apple Developer Program or Apple Developer Enterprise Program, or a 2023 Swift Student Challenge applicant.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      Xcode 15 beta now available

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        The Xcode 15 beta supports the latest SDKs for iOS, iPadOS, macOS, tvOS, and watchOS. This version of Xcode helps you code and design your apps faster with enhanced code completion, interactive previews, and live animations. Use Git staging to craft your next commit without leaving your code. Explore and diagnose your test results with redesigned test reports with video recording. And start deploying seamlessly to TestFlight and the App Store from Xcode Cloud.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        Learn more

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        WWDC23 schedule and lab requests now available

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          Check out the session schedule to plan your week! Sessions will be posted daily and will include links to resources and forums tags. And you can now request one-on-one lab appointments to get your questions answered, whether you’re just starting out or need to solve an advanced issue.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          Learn more

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          System Services

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            System Services

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            Empower your app by leveraging the system.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            Accessibility &amp; Inclusion

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              Accessibility & Inclusion

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              Build great apps and games for everyone.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              Swift

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                Swift

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                Learn the latest updates for Swift.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                Business &amp; Education

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  Business & Education

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  Deploy and manage Apple devices in your classroom or office.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  App Services

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    App Services

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    Extend your app's experience.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    Privacy &amp; Security

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      Privacy & Security

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      Tighten the privacy and security of your apps and games.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      Graphics &amp; Games

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        Graphics & Games

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        Launch your games and level up your graphics.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        Design

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          Design

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          Create compelling interfaces and experiences.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          Health &amp; Fitness

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            Health & Fitness

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            Get your health and fitness app in great shape.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            App Store Distribution &amp; Marketing

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              App Store Distribution & Marketing

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              Market your app and grow your audience.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              SwiftUI &amp; UI Frameworks

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                SwiftUI & UI Frameworks

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                Build interfaces that feel right at home on Apple platforms.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                Developer Tools

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  Developer Tools

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  Explore the tools you need to build the next great app or game.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  Maps &amp; Location

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    Maps & Location

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    Help people find where they are and where they’re going.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    Safari &amp; Web

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      Safari & Web

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      Explore Safari and web technologies.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      Audio &amp; Video

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        Audio & Video

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        Build audio and video experiences for your app.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        Coding &amp; Design Essentials

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          Coding & Design Essentials

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          New to WWDC? Start right here.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          Upcoming tax changes for apps, in-app purchases, and subscriptions

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            The App Store’s commerce and payments system was built to empower you to conveniently set up and sell your products and services at a global scale in 44 currencies across 175 storefronts. Apple administers tax on behalf of developers in over 70 countries and regions and provides you with the ability to assign tax categories to your apps and in‑app purchases. Periodically, we update your proceeds in certain regions based on changes in tax regulations.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            On May 31, your proceeds from the sale of apps and in‑app purchases (including auto‑renewable subscriptions) will be adjusted to reflect the tax changes listed below. Prices will not change.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            • Ghana: Increase of the VAT rate from 12.5% to 15%.
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            • Lithuania: Reduction of the VAT rate from 21% to 9% for eligible e‑books and audiobooks.
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            • Moldova: Reduction of the VAT rate from 20% to 0% for eligible e‑books and periodicals.
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            • Spain: Digital services tax of 3%.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            Due to changes to tax regulations in Brazil, Apple now withholds taxes for all App Store sales in Brazil. We’ll administer the collection and remittance of taxes to the appropriate tax authority on a monthly basis. You can view the amount of tax deducted from your proceeds starting in June 2023 with your May earnings. Developers based in Brazil aren’t impacted by this change.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            Once these changes go into effect, the Pricing and Availability section of My Apps will be updated in App Store Connect. As always, you can change the prices of your apps and in‑app purchases (including auto‑renewable subscriptions) at any time. And now you can change them for any storefront with 900 price points to choose from.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            Code new worlds

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              WWDC23 is almost here. We’ll be kicking off with the Apple Keynote on June 5 at 10:00 a.m. PT. Watch online at apple.com or in the Apple Developer app. You can even use SharePlay to watch with friends.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              Activities are now open for sign-up for eligible developers. Designed to connect you with the developer community and Apple experts, they’ll feature Q&As, Meet the Presenters, and community icebreakers in online group chats.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              Learn more

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              Sign up

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              Upcoming changes to the App Store receipt signing intermediate certificate

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                As part of ongoing efforts to improve security and privacy on Apple platforms, the App Store receipt signing intermediate certificate that’s used to verify the sale of apps and associated in‑app purchases is being updated to use the SHA‑256 cryptographic algorithm. This update will be completed in multiple phases and new apps and app updates may be impacted, depending on how they verify receipts.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                What to expect

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                If your app verifies App Store transactions using the AppTransaction and Transaction APIs, or the verifyReceipt web service endpoint, no action is required.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                If your app validates App Store receipts on device, make sure your app will support the SHA-256 version of this certificate. New apps and app updates that don’t support the SHA-256 version of this certificate will no longer be accepted by the App Store starting August 14, 2023.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                Important dates
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                • June 20, 2023. Receipts in the sandbox environment will be signed with the SHA‑256 version of this certificate for devices running a minimum of iOS 16.6, iPadOS 16.6, tvOS 16.6, watchOS 9.6, or macOS Ventura 13.5.
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                • August 14, 2023. Receipts in new apps and app updates submitted to the App Store, as well as all apps in sandbox, will be signed with the SHA‑256 intermediate certificate.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                For more details, view TN3138: Handling App Store receipt signing certificate change.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                Apple notary service update

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  As announced last year at WWDC, if you notarize your Mac software with the Apple notary service using the altool command-line utility or Xcode 13 or earlier, you’ll need to transition to the notarytool command-line utility or upgrade to Xcode 14 or later. Starting November 1, 2023, the Apple notary service will no longer accept uploads from altool or Xcode 13 or earlier. Existing notarized software will continue to function properly.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  The Apple notary service is an automated system that scans Mac software for malicious content, checks for code-signing issues, and returns the results quickly. Notarizing your software assures users that Apple has checked it for malicious software and none was detected.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  Learn about migrating to the latest notarization tool

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  Learn about notarizing macOS software

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  Apple Design Award finalists announced

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    The Apple Design Awards celebrate apps and games that excel in the categories of Inclusivity, Delight and Fun, Interaction, Social Impact, Visuals and Graphics, and Innovation. Discover this year’s finalists, then check back June 5 at 6:30 p.m. PT to learn about the winners.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    Discover the finalists

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    Swiftly developing

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      Get ready for an action-packed online experience at WWDC23. Join the developer community for a week of sessions, labs, and activities, starting June 5 at 10:00 a.m. PT.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      Find out what's ahead

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      Get ready with the latest beta releases

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        The beta versions of iOS 16.6, iPadOS 16.6, macOS 13.5, tvOS 16.6, and watchOS 9.6 are now available. Get your apps ready by confirming they work as expected on these releases. And to take advantage of the advancements in the latest SDKs, make sure to build and test with Xcode 14.3.1.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        To check if a known issue from a previous beta release has been resolved or if there’s a workaround, review the latest release notes. Please let us know if you encounter an issue or have other feedback. We value your feedback, as it helps us address issues, refine features, and update documentation.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        View downloads and release notes

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        Learn about testing a beta OS

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        Learn about sending feedback

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        Report bugs effectively

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          Bugs are an inevitable part of the development process. Though they can be frustrating, you can help squash these sorts of problems quickly by identifying the issue you’re running into, reproducing it, and filing a report through Feedback Assistant.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          Discover how you can make sure your feedback is clear and actionable.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          Learn more about sending feedback >

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          Q&amp;A with the passkeys team

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            Get ready for a world without passwords.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            Passkeys are a replacement for passwords, offering a faster, easier, and more secure sign-in experience for your apps and websites. They’re strong, resistant to phishing, and designed to work across Apple devices and nearby non-Apple devices. Best of all, there’s nothing for people to create, guard, or remember.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            To help explain how to implement passkeys, the Apple privacy and security team hosted a Q&A to answer common questions about device support, use cases, account recovery, and more. Here are some highlights from that conversation.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            How do passkeys work?

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            Passkeys are based on public key cryptography, which matches a private key saved on a device with a public key sent to a web server. When someone signs in to an account, their private key is verified by your app or website’s public key. That private key never leaves their device, so apps and websites never have access to it — and can’t lose it or reveal it in a hacking or phishing attempt. There’s nothing secret about the public key; it offers no access to anything until paired with the private key.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            Which devices support passkeys?

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            Passkeys work on devices running a minimum of iOS 16 on iPhone 8; iPadOS 16 on iPad 5th generation, iPad mini 5th generation, iPad Air 3rd generation, all iPad Pro models that offer Touch ID or Face ID; macOS Ventura; and tvOS 16. Passkeys are also supported in Safari 16 on macOS Monterey and Big Sur.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            When Touch ID or Face ID can’t be used, people can enter their device passcode or system password to authenticate passkey credentials.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            How do I adopt passkeys?

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            The first step is to adopt WebAuthn on your back-end server and add our platform-specific API to your app. Take a deeper dive into next steps by watching the video below:

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            Meet passkeys Watch now What happens if a device is lost or stolen?

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            Data remains safe. Passkeys are end-to-end encrypted through iCloud Keychain and require biometrics, such as Face ID or Touch ID, or the device passcode to decrypt them. Without these, passkeys remain securely stored on the lost device. For extra peace of mind, you can always remotely wipe your device with Find My.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            What does account recovery look like for someone who’s only ever signed in with a passkey?

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            The recovery method is independent of the authentication mechanism. Apps and websites are welcome to maintain the same recovery methods they use today (such as sending a link in an email to create a new passkey). Recovery will likely be a much less common scenario with passkeys, which are saved by the device. There’s nothing for a human to forget.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            Can someone have multiple passkeys for my app; for instance, passkeys generated from multiple devices?

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            Yes, someone can have one passkey per account per platform. In the special case that someone has more than one account for an app, they’ll have discrete passkeys for each account too.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            What’s the difference between passkeys and multifactor authentication?

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            Multifactor authentication adds additional layers of security on top of an existing password, but generally still leaves the possibility of phishing. Since passkeys eliminate the most pressing problems with passwords and are resistant to phishing, additional user-visible steps aren’t needed.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            Is it possible to use an email address as the visible account identifier instead of a username?

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            Yes, it’s definitely possible. Our videos and documentation use usernames and email addresses as examples. Nothing about account identifiers has to change.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            Resources Meet passkeys Watch now Spotlight on: Passkeys View now

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            Passkeys overview

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            About the security of passkeys

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            Supporting passkeys

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            Connecting to a service with passkeys

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            Secure your apps and games

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              Security is at the core of every Apple platform. Discover how you can help guard your apps and games against potential threats, add support for passkeys, streamline authentication and authorization flows, and more. You’ll also get to know Developer Mode, which lets you develop, test, and deploy your products.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              Videos Get to know Developer Mode Watch now Improve DNS security for apps and servers Watch now Meet passkeys Watch now Replace CAPTCHAs with Private Access Tokens Watch now Streamline local authorization flows Watch now What’s new in notarization for Mac apps Watch now Mitigate fraud with App Attest and DeviceCheck Watch now Safeguard your accounts, promotions, and content Watch now Secure your app: threat modeling and anti-patterns Watch now Feature stories Spotlight on: Passkeys View now Q&A with the passkeys team View now Resources

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              Security Overview

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              Spotlight on: Passkeys

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                If you’ve ever dreamed of creating a more secure and phishing-resistant sign-in experience, we have good news.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                “There is a high chance that in a few years, Apple’s release of passkeys as part of iOS 16 will be remembered as the beginning of a revolutionary change in how companies implement sign-in for their products,” wrote Matthias Keller, Kayak chief scientist and SVP of technology, in a 2022 op-ed piece on the subject.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                Passkeys offer a faster, easier, and more secure sign-in experience for your apps and websites. They’re strong, resistant to phishing, and designed to work across Apple devices, as well as nearby non-Apple devices. And because they’re integrated with Touch ID and Face ID, people can use passkeys like they would any other sign-in system or routine.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                A passkey is a cryptographic entity used in place of a password that’s made up of two keys: one public, one private. The public key is registered with an app or website and kept on a web server, while the private key is stored on devices. When someone attempts to sign in, the app or website creates a challenge. The private key signs the challenge to create a signature and the public key is used to verify that signature without revealing what the private key is.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                While there’s a lot going on behind the scenes, most people won’t know — or need to think about — any of it. With passkeys, there’s nothing to create, guard, or remember. Plus, the private key is stored in iCloud Keychain and is end-to-end encrypted for another layer of security.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                Kayak: “You just initiate the process”

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                Kayak’s Keller isn’t just a longtime digital security evangelist with years of history in the field. He's also a dad — and that poses its own host of security challenges.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                “Between activities and school, I’m constantly creating accounts and passwords, all of which have a variety of stipulations,” Keller says. “Some can’t be longer than 16 characters, some require special symbols, and others won’t even recognize an exclamation point. And I know from experience that companies face similar challenges when it comes to protecting passwords.”

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                Keller has been involved with Kayak’s various login approaches throughout his 10 years with the company. Prior to passkeys, the app relied largely on “magic links” sent via email. “But it was getting more and more complex to ensure the security of magic links, especially when supporting logins across devices,” Keller says.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                Between activities and school, I'm constantly creating accounts and passwords, all of which have a variety of stipulations.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                Matthias Keller, Kayak chief scientist and SVP of technology

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                When Keller first heard about passkeys, he knew they were right for Kayak. “The moment it clicked for me was when I saw the first prototype and how easy it was to use,” he says. Kayak was one of the very first to support passkeys, releasing their update at the same time as the feature’s public release in September 2022.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                The Kayak team was able to adopt passkeys so quickly in part because of the underlying framework and documentation supporting the feature. “Working on the server is my day-to-day, but I’m not afraid of doing a little bit of Swift, too,” he says. “Luckily, integrating passkeys was light on the UI side. We only had to initiate the experience provided by Apple.”

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                Feedback was overwhelmingly positive. In the feature’s first three weeks of availability, thousands of people created passkeys on Kayak. Almost 20 percent of those were existing users who manually opted into the new technology.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                “The world before passkeys was broken,” he says. “You have all these obscure password rules, as well as expiration and compliance issues — and it can be extremely expensive to offer authentication because you have to buy security products or hire someone to run it for you.” Keller’s work at Kayak is part of a larger drive to get more companies around the world to support this new open standard — one that protects its developers as much as its customers. “You no longer need to protect millions of passwords. Now we only store public keys, which are pretty useless to hackers.”

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                For Keller, passkeys are now a crucial part of Kayak’s security strategy. “We’ve got a long journey until the last password is gone, but it's exciting to see where we're headed,” he says.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                Robinhood: "We're talking about the emotional angle"

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                For investment app Robinhood, passkeys provide a key advantage over other secure sign-in options: speed.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                Robinhood is a product where you may want to sign in and complete a time-sensitive action,” says Hannarae Nam, the app’s product manager for account security. “Maybe the market’s opening and [you] want to make a trade immediately.” Typing a password or engaging in two-factor authentication can eat up precious seconds — and could cost you a deal or a valuable trade.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                We're talking about the emotional angle of instantly accessing your account.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                Yong Rhee, Robinhood product lead for customer trust and safety

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                With passkeys, the app can provide a speedy login process that also offers maximum security. “It’s critical to understand that we’re not talking about just the ability to engage with Robinhood to invest and trade,” says Yong Rhee, the product lead for customer trust and safety. “We’re talking about the emotional angle of instantly accessing your account.”

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                Ensuring that customers aren’t locked out is “critical” to Robinhood, says Rhee. Passkeys are managed by the operating system and backed up, synced, and available across all of someone’s devices. There's no typing needed and nothing to remember. And people can easily get back in to their accounts even if they lose their phone.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                Robinhood’s security team pushed for passkeys early as a potential solution for their customers. “They’ve been a strong proponent of bringing up the vulnerabilities of passwords,” says Rhee. The team rolled out passkeys to a percentage of customers in December 2022, though they plan to continue maintaining their existing password and two-factor authentication system as passkeys adoption rolls out. “I think when customers catch up to the technology, they’ll understand and feel more confident in account security,” says Rhee.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                Instacart: “It seemed like a perfect match”

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                Instacart senior mobile engineer Josh Schroeder was on paternity leave when passkeys were introduced at WWDC22, but he made a note to dig into the idea upon his return. “Between the reduced friction and improved security, it seemed like a perfect match,” he says.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                The Instacart team signed off on the idea quickly, encouraged by the opportunity to reduce sign-in friction. “That was the biggest selling point for me,” says Brandon Lawrence, Instacart’s senior software engineer. “Well, that and not having to remember another password.”

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                We believe in passkeys, and we think this will become really common.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                Josh Schroeder, Instacart senior mobile engineer

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                For Instacart, there was a second benefit as well: the opportunity to pare down duplicate accounts. “When they don’t remember their password, a lot of people just create another account,” says Schroeder. Passkeys avoid that unnecessary (and annoying) duplication. Because devices keep track of passkeys, there's nothing to remember.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                The early implementation process made Lawrence — who spent part of his pre-tech career as a meteorologist in the Marines — feel like something of a passkeys pioneer. “For much of what we build, we can look at the many people who’ve done it before. This time there was a lot more exploration, a little more feeling like we were in uncharted territory. Once we got it into place, it was relatively smooth.”

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                Today, passkeys are presented as the default sign-in option when creating an Instacart account with an email address (although if someone declines, the app offers the option to create a traditional password). More than half of new Instacart customers who created accounts with an email address have adopted the feature, and plans are underway to gradually convert existing accounts as well. “We believe in passkeys,” says Schroeder, “and we think this will become really common.”

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                Resources Meet passkeys Watch now Q&A with the passkeys team View now

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                Passkeys overview

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                About the security of passkeys

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                Supporting passkeys

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                Connecting to a service with passkeys

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                Get ready to help customers resolve billing issues without leaving your app

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  Soon it will be easier than ever for your customers to resolve payment issues, so they can stay subscribed to your content, services, and premium features. Starting this summer, if an auto-renewable subscription doesn’t renew due to a billing issue, a system-provided sheet appears in your app with a prompt that lets customers update their payment method for their Apple ID. No action is required to adopt this feature. Starting today, you can get familiar with the sheet in Sandbox. You can also test delaying or suppressing it using messages and display in StoreKit. This feature will require a minimum of iOS 16.4 or iPadOS 16.4.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  All of this adds to existing powerful App Store features that help you retain subscribers. For example, if a subscription is in the billing retry state, Apple uses machine learning to optimize payment retries for the best possible recovery rate. And when you enable Billing Grace Period, customers can continue accessing their subscriptions while Apple attempts to collect payment.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  Learn about the system-provided sheet

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  Learn how to test billing issues in Sandbox

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  Preparing for the enhanced global pricing update on May 9

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    The App Store’s world-class commerce and payments system provides a convenient and effective way to set equalized prices across international markets, adapt to foreign exchange rate or tax changes, and manage prices per storefront. Last month, we introduced major pricing upgrades, including enhanced global pricing, across all purchase types. Now more customer friendly, the new price points follow the most common conventions in each country or region, and are globally equalized to your selected base country or region using publicly available exchange rate information from financial data providers.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    As a reminder, on May 9, 2023, pricing for existing apps and one-time in-app purchases will be updated across App Store storefronts using your current price in the United States as the basis — unless you’ve made relevant updates after March 8, 2023. You can update your base country or region at anytime using App Store Connect or the App Store Connect API. If you choose to do so, prices in your selected base country or region won’t be adjusted when prices are globally equalized on the App Store to account for foreign currency changes or new taxes. You can also choose to manually adjust prices on multiple storefronts of your choice instead of using the equalized price.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    Learn how to select a base country or region

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    Learn how to set in-app purchase availability

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    Learn how to view the new pricing

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    Recent content on Mobile A11y

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    iOS Accessibility Values

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      For iOS, Accessibility values are one of the building blocks of how Accessibility works on the platform, along with traits, labels, hints, and showing/hiding elements. If you’re familiar with WCAG or web accessibility, accessibility values are the value part of WCAG 4.1.2: Name, Role, Value. Values Not every element in your view will have a value - in fact, most won’t. Any element that ‘contains’ some data, data that is not included in the element’s label requires an accessibility value to be set.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      iOS UIKit Accessibility traits

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        Accessibility traits on iOS is the system by which assistive technologies know how to present your interface to your users. The exact experience will vary between assistive technologies, in some cases they may change the intonation of what VoiceOver reads, or add additional options for navigation, sometimes they will disable that assistive technology from accessing the element, or change how the assistive tech functions. They are the ‘Role’ part of the fundamental rule of making something accessible to screen readers - WCAG’s 4.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        iOS Custom Accessibility Actions

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          When testing your app with VoiceOver or Switch Control, a common test is to ensure you can reach every interactive element on screen. If these assistive technologies can’t focus all of your buttons how will your customers be able to interact fully with your app? Except there are times when hiding buttons from your assistive technology users is the better choice. Consider an app with a table view that has many repeating interactive elements - this could be a social media app where ’like, share, reply’ etc is repeated for each post.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          Test Your App's Accessibility with Evinced

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            Disclosure: Evinced has paid for my time in writing this blog, and I have provided them feedback on the version of their tool reviewed and an early beta. I agreed to this because I believe in the product they are offering. Testing your app for accessibility is an essential part of making an accessible app, as with any part of the software you build, if you don’t test it, how can you be sure it works?

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            How Do I Get My App an Accessibility Audit?

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              This is a common question I get asked - how do I go about arranging an accessibility audit for my app so I know where I can make improvements? If you’re truly looking for an answer to that question then I have a few options for you below, but first, are you asking the right question? Accessibility Isn’t About Box Ticking You can’t make your app accessible by getting a report, fixing the findings, and accepting it as done.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              Quick Win - Start UI Testing

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                I’ll admit, adding UI testing to an app that currently doesn’t have it included is probably stretching the definition of quick win, but the aim here isn’t 100% coverage - not right away anyway. Start small and add to your test suite as you gain confidence. Even a small suite of crucial happy-path UI tests will help to ensure and persist accessibility in your app. And the more you get comfortable with UI tests the more accessible your apps will become, because an app that is easy to test is also great for accessibility.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                Quick Win - Support Dark Mode

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  Many people don’t realise dark mode is an accessibility feature. It’s often just considered a nice to have, a cool extra feature that power users will love. But dark mode is also a valuable accessibility feature. Some types of visual impairment can make it painful to look at bright colours, or large blocks of white might wash over the black text. Some people with dyslexia or Irlen’s Syndrome can struggle to read black text on a white background.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  Quick Win - Support Landscape

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    If you have a regulatory requirement to provide accessibility in your app (spoiler, you do) the chances are it will say you have a requirement to reach WCAG AA. While this is likely meaningless to anyone other an accessibility professionals, in short it means you are providing the minimum level of accessibility features required to make your app usable by the majority of people. This post is about one such requirement, the jazzily titled Success Criterion 1.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    Quick Win - Image Descriptions

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      Images are a major part of our apps. They add meaning and interest, they give your app character and context. The adage is that a picture is worth a thousand words. But if you can’t see the image clearly, how do you know what those words are? If you aren’t providing image descriptions in your app many of your users will be missing out on the experience you’ve crafted. The result can be an app thats missing that spark an character, or worse an app thats just meaningless and unusable.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      Quick Win - Text Contrast

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        How many shades of grey do you use in your app? OK, maybe thats a bit cruel towards designers, grey is a great colour, but the problem with grey is that it can be deceptively difficult to distinguish from a background. And this problem is not just limited to greys - lighter colours too can blend into the background. This effect can be heightened too for people who have blurred or obscured vision, or one of many forms of colour blindness.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        iOS 14: Custom Accessibility Content

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          Each year at WWDC Xcode Santa brings us exciting new APIs to play with, and this year our accessibility present is Customized Accessibility Content. This API flew under the radar a little, I’m told this is because it’s so new there wasn’t even time for inclusion at WWDC. But this new feature helps to solve a difficult question when designing a VoiceOver interface - where is the balance between too much and too little content.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          Accessibility Review: Huh? - International languages

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            The Accessibility Review series uses real world apps to provide examples of common accessibility issues and provide tips on how to fix them. Each of the developers has kindly volunteered their app to be tested. Huh? is a dictionary and thesaurus app from Peter Yaacoub. Enter a word into the search bar then choose a dictionary service. Press search and the app will present your chosen service’s entry for the term you entered.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            Accessibility Review: Figure Case - Button Labels

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              The Accessibility Review series uses real world apps to provide examples of common accessibility issues and provide tips on how to fix them. Each of the developers has kindly volunteered their app to be tested. Figure Case is an app to help organise a tabletop miniature collection created by Simon Nickel. The app helps to track miniatures you own, and what state they currently find themselves in - unassembled, assembled, or painted.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              Accessibility Review: Daily Dictionary - Screen changes

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                The Accessibility Review series uses real world apps to provide examples of common accessibility issues and provide tips on how to fix them. Each of the developers has kindly volunteered their app to be tested. Daily Dictionary is an app from Benjamin Mayo providing a new word every day with definitions and real-world uses designed to help increase your vocabulary. Assessing the app, I noticed Benjamin has made a design decision around presenting the app’s settings.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                iOS Attributed Accessibility Labels

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  Attributed accessibility labels are an incredible tool for making some next-level accessible experiences. They let you tell VoiceOver not just what to speak, but how to say it too. Using the accessibilityAttributedLabel property you can provide an NSAttributedString to VoiceOver, much the same way you would provide an NSAttributedString to a label’s attributedText property to display a string with an underline or character colour for example. The difference here is that all of our attributes are instructions for VoiceOver.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  Writing Great iOS Accessibility Labels

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    A good accessibility label lets your customer know exactly what a control does in as few words as possible, without having to rely on implied context. Don’t Add the Element Type iOS already knows your button is a button and your image is an image, it does this using an accessibility trait. If you label your button as ‘Play button’ your VoiceOver customers will hear ‘Play button. Button.’ Keep it Succinct Don’t frustrate your customer by adding too much information to your labels.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    When to use Accessibility Labels

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      There’s a few circumstances when you’ll want to set your own accessibility label, such as… An interactive element that you haven’t given a text value to, such as an image button. An interactive element with a long visual label. An interactive element with a short visual label that takes context from your design. A control or view you have created yourself or built by combining elements. Images of text. Elements Without a text value Take the controls for a music player as an example.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      iOS Accessibility Labels

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        This blog was inspired by Jeff Watkins’ series of blogs on UIButton. UIButton is a fundamental part of building interfaces on iOS. So much so, that it probably doesn’t get the love it deserves. But it’s also really powerful and customisable when used correctly. Accessibility labels on iOS I feel are very similar. They’re fundamental to how accessibility works on iOS, yet I think they suffer from a few PR issues.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        A11y Box Android

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          A few months ago I shared a project I’d been working on for iOS exploring the accessibility API available on that platform. The Android accessibility API is equally large and full featured, and really deserves the same treatment. So here’s A11y Box for Android. A11y Box for Android is an exploration of what is available on the Android accessibility api and how you can make use of it in your apps.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          Mobile A11y Talk: Accessibility in SwiftUI

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            I was supposed to be attending the 2020 CSUN Assistive Technology conference to present a couple of talks, unfortunately with COVID-19 starting to take hold at that time, I wasn’t able to attend. In lieu of attending I decided to record one of the talks I was scheduled to present on Accessibility in SwiftUI. SwiftUI is Apple’s new paradigm for creating user interfaces on Apple platforms, and it has a bunch of new approaches that really help create more accessible experiences.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            A11y Box iOS

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              iOS’ UIAccessibility API is huge. I like to think I know it pretty well, but I’m always being surprised by discovering features I previously had no idea about. Like many things on iOS, the documentation for UIAccessibility is not always complete, even for parts of the API that have been around for years. In an attempt to help spread the knowledge of some of the awesome things UIAccessibility is capable of, I’ve created A11y Box for iOS.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              Android Live Regions

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                Live Regions are one of my favourite accessibility features on Android. They’re a super simple solution to a common accessibility problem that people with visual impairments can stumble across. Say you have a game app, really any type of game. Your user interacts with the play area, and as they do, their score increases or decreases depending on your customer’s actions. In this example, the score display is separate to the element your customer is interacting with.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                A11yUITests: An XCUI Testing library for accessibility

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  A11yUITests is an extension to XCTestCase that adds tests for common accessibility issues that can be run as part of an XCUITest suite. I’ve written a detailed discussion of the tests available if you’re interested in changing/implementing these tests yourself. Alternatively, follow this quick start guide. Getting Started Adding A11yUITests I’m assuming you’re already familiar with cocoapods, if not, cocoapods.org has a good introduction. There is one minor difference here compared to most cocoapods, we’re not including this pod in our app, but our app’s test bundle.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  XCUITests for accessibility

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    For a while now I’ve been looking at possibilities for automated accessibility testing on iOS. Unfortunately, I’ve not found any option so far that I’m happy with. I am a big fan of Apple’s XCUI Test framework. Although it has its limitations, I believe there’s scope for creating valid accessibility tests using this framework. Over the last few months I’ve been trying things out, and here’s what I’ve come up with.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    Resources

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      This is a personally curated list of resources I have used and think others may find helpful too. I’m always looking for new high quality mobile accessibility and inclusion resources to add here. Please share any you find with me via email or Twitter. Code Android Android Developers: Build more accessible appsAndroid’s developer documentation for Accessibility, including design, building & testing. With videos, code samples, and documentation. Android: Make apps more accessibleGoogle’s guide to improving accessibility on Android

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      Review: Accessibility for Everyone - Laura Kalbag

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        Laura’s introduction to web accessibility jumped out to me because it’s available as an audiobook. Being dyslexic I struggle to read, so prefer to listen to audiobooks where available. Unfortunately, most technical books aren’t available as audiobooks for a couple of potentially obvious reasons. Hearing code or descriptions of diagrams and illustrations read aloud may not be the best experience for an audiobook. As such, this book choses to leave those out of the audio version.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        A11y is not accessible

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          Accessibility is a long word. It’s not the simplest of words to read or to spell, so it seems like a word that would be a good candidate for abbreviation. The common abbreviation of accessibility is a11y. We take the A and Y from the beginning and end of accessibility, and 11 for the number of letters in between. This abbreviation also creates a pleasing homophone for ‘ally.’ The irony of this abbreviation is that a11y isn’t accessible.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          About Mobile A11y

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            About Mobile A11y Mobile A11y is a collection of blogs and resources about how we as mobile developers can improve accessibility on mobile devices. From time to time the blog might also touch on related topics such as digital inclusion, and other topics around ethics in technology. The site is aimed at mobile developers and is written by a mobile developer. I hope this means other mobile developers will find the content relatable and engaging, and you’ll find learning about mobile accessibility along with me helpful.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            SwiftUI Accessibility

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              Accessibility is important. We can take that as a given. But as iOS devs we’re not always sure how to make the most of the accessibility tools that Apple have provided us. We’re lucky as iOS developers that we work on such a forward-thinking accessibility platform. Many people consider Apple’s focus on accessibility for iOS as the driver for other technology vendors to include accessibility features as standard. To the point that we now consider accessibility an expected part of any digital platform.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              SwiftUI Accessibility: Semantic Views

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                Semantic views are not new to SwiftUI, but changes in SwiftUI mean creating them is simple. Semantic views are not so much a language feature. They’re more a technique for manipulating the accessible user interface and improving the experience for assistive technology users. A what view? A semantic view is not one view, but a collection of views grouped together because they have meaning (or semantic) together. Take a look at this iOS table view cell from the files app.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                SwiftUI Accessibility: User Settings

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  SwiftUI allows us to read environmental values that might affect how we want to present ­­our UI. Things like size classes and locale for example. We also get the ability to read some of the user’s chosen accessibility settings allowing us to make decisions that will best fit with your customer’s preference. Why? Before we cover what these options are and how to detect them I think it’s important to briefly cover why we need to detect them.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  SwiftUI Accessibility: Attributes

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    When a customer enables an assistive technology to navigate your app the interface that technology navigates isn’t exactly the same as the one visible on the screen. They’re navigating a modified version that iOS creates especially for assistive technology. This is known as the accessibility tree or accessible user interface. iOS does an incredible job at creating the AUI for you from your SwiftUI code. We can help iOS in creating this by tweaking some element’s accessibility attributes.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    SwiftUI Accessibility: Traits

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      Accessibility traits are a group of attributes on a SwiftUI element. They inform assistive technologies how to interact with the element or present it to your customer. Each element has a selection of default traits, but you might need to change these as you create your UI. In SwiftUI there are two modifiers to use for traits, .accessibility(addTraits: ) and .accessibility(removeTraits: ) which add or remove traits respectively. Each modifier takes as its argument either a single accessibility trait or a set of traits.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      Review: Design Meets Disability - Graham Pullin

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        Design Meets Disability was recommended to me by accessibility consultant Jon Gibbins while we were sharing a long train journey through mid-Wales. We were talking, amongst many things, about our love for Apple products and their design. I am a hearing aid wearer, my aid is two-tone grey. A sort of dark taupe grey above, and a darker, almost gun-metal grey below. There’s a clear tube into my ear. This is fine, I don’t hate it.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        Podcast: iPhreaks - iOS Accessibility

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          I was asked to guest on the iPhreaks podcast to discuss iOS accessibility. We talked about why accessibility is important, how you can improve it in your apps, and some of the changes iOS 13 and SwiftUI bring. unfortunatley iPhreaks don’t provide a transcript, but they do provide a comprehensive write-up on their site.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          SwiftUI Accessibility: Accessible User Interface

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            Take a look at your app. Notice the collection of buttons, text, images, and other controls you can see and interact with that make up your app’s user interface. When one of your customers navigates your app with Voice Control, Switch Control, VoiceOver, or any other assistive technology, this isn’t the interface they’re using. Instead, iOS creates a version of your interface for assistive technology to use. This interface is generally known as the accessibility tree.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            Mobile A11y Talk: Accessibility without the 'V' Word

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              I was honoured in 2019 to be able to give my first full conference talk at CodeMobile. I was then lucky enough to be able to repeat that talk at NSLondon, NSManchester, and SWMobile meetups. As an iOS developer, I know accessibility is important for a huge range of people. But at times I think I can treat it like an afterthought. Accessibility Without the ‘V’ Word covers a skill I think we as software engineers would benefit from developing - empathy towards our users.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              SwiftUI Accessibility: Sort Priority

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                Assistive technology, such as VoiceOver, works in natural reading direction. In English, and most other languages, this means top left through to the bottom right. Mostly this is the right decision for assistive technology to make. This is the order anyone not using assistive technology would experience your app. Sometimes though, we make designs that don’t read in this way. By using the .accessibility(sortPriority: ) modifier we can set the order in which assistive technology accesses elements.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                SwiftUI Accessibility - Named Controls

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  One big accessibility improvement in SwiftUI comes in the form of named controls. Nearly all controls and some non-interactive views (see Images) can take a Text view as part of their view builder. The purpose of this is to tie the meaning to the control. Toggle(isOn: $updates) { Text("Send me updates") } Imagine a UIKit layout with a UISwitch control. We’d most likely right align the switch, and provide a text label to the left.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  SwiftUI Accessibility: Dynamic Type

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    Like all accessibility features, Dynamic Type is about customisability. Many of your customers, and maybe even you, are using Dynamic Type without even considering it an accessibility feature. Dynamic type allows iOS users to set the text to a size that they find comfortable to read. This may mean making it a little larger so it’s easier to read for those of us who haven’t yet accepted we might need glasses.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    SwiftUI Accessibility: Images

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      Images in SwiftUI are accessible by default. This is the opposite of what we’d experience in UIKit, where images are not accessible unless you set isAccessibilityElement to true. Sometimes making images not accessible to VoiceOver is the right decision. Like when using a glyph as a redundant way of conveying meaning alongside text. An example of this would be displaying a warning triangle next to the text ‘Error’ or a tick next to ‘success’.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      Baking Digital Inclusion Into Your Mobile Apps

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        I was asked by Capital One to contribute an accessibility piece to the Capital One Tech Medium. The blog, titled Baking Digital Inclusion Into Your Mobile Apps, briefly covers what we mean by disability and what we can do to make our mobile apps work better for everyone.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        What The European Accessibility Act (Might) Mean for Mobile Development

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          The European Accessibility Act, or EAA is due to become law in Europe later this year, and it defines some specific requirements for mobile. In fact, its the first accessibility legislation that I’m aware of, anywhere, that explicitly covers mobile apps. Since 2012 the European Union has been working on standardising accessibility legislation across Europe. The ultimate aim is to both improve the experience for those who need to use assistive technology, but also to simplify the rules business need to follow on accessibility.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          Building with nightly Swift toolchains on macOS

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            The Swift website provides nightly builds of the Swift compiler (called toolchains) for download. Building with a nightly compiler can be useful if you want to check if a bug has already been fixed on main, or if you want to experiment with upcoming language features such as Embedded Swift, as I’ve been doing lately. A toolchain is distributed as a .pkg installer that installs itself into /Library/Developer/Toolchains (or the equivalent path in your home directory). After installation, you have several options to select the toolchain you want to build with: In Xcode In Xcode, select the toolchain from the main menu (Xcode > Toolchains), then build and/or run your code normally. Not all Xcode features work with a custom toolchain. For example, playgrounds don’t work, and Xcode will always use its built-in copy of the Swift Package Manager, so you won’t be able to use unreleased SwiftPM features in this way. Also, Apple won’t accept apps built with a non-standard toolchain for submission to the App Store. On the command line When building on the command line there are multiple options, depending on your preferences and what tool you want to use. The TOOLCHAINS environment variable All of the various Swift build tools respect the TOOLCHAINS environment variable. This should be set to the desired toolchain’s bundle ID, which you can find in the Info.plist file in the toolchain’s directory. Example (I’m using a nightly toolchain from 2024-03-03 here): # My normal Swift version is 5.10 $ swift --version swift-driver version: 1.90.11.1 Apple Swift version 5.10 (swiftlang-5.10.0.13 clang-1500.3.9.4) # Make sure xcode-select points to Xcode, not to /Library/Developer/CommandLineTools # The Command Line Tools will ignore the TOOLCHAINS variable. $ xcode-select --print-path /Applications/Xcode.app/Contents/Developer # The nightly toolchain is 6.0-dev $ export TOOLCHAINS=org.swift.59202403031a $ swift --version Apple Swift version 6.0-dev (LLVM 0c7823cab15dec9, Swift 0cc05909334c6f7) Toolchain name vs. bundle ID I think the TOOLCHAINS variable is also supposed to accept the toolchain’s name instead of the bundle ID, but this doesn’t work reliably for me. I tried passing: the DisplayName from Info.plist (“Swift Development Snapshot 2024-03-03 (a)”), the ShortDisplayName (“Swift Development Snapshot”; not unique if you have more than one toolchain installed!), the directory name, both with and without the .xctoolchain suffix, but none of them worked reliably, especially if you have multiple toolchains installed. In my limited testing, it seems that Swift picks the first toolchain that matches the short name prefix (“Swift Development Snapshot”) and ignores the long name components. For example, when I select “Swift Development Snapshot 2024-03-03 (a)”, Swift picks swift-DEVELOPMENT-SNAPSHOT-2024-01-30-a, presumably because that’s the “first” one (in alphabetical order) I have installed. My advice: stick to the bundle ID, it works. Here’s a useful command to find the bundle ID of the latest toolchain you have installed (you may have to adjust the path if you install your toolchains in ~/Library instead of /Library): $ plutil -extract CFBundleIdentifier raw /Library/Developer/Toolchains/swift-latest.xctoolchain/Info.plist org.swift.59202403031 # Set the toolchain to the latest installed: export TOOLCHAINS=$(plutil -extract CFBundleIdentifier raw /Library/Developer/Toolchains/swift-latest.xctoolchain/Info.plist) xcrun and xcodebuild xcrun and xcodebuild respect the TOOLCHAINS variable too. As an alternative, they also provide an equivalent command line parameter named --toolchain. The parameter has the same semantics as the environment variable: you pass the toolchain’s bundle ID. Example: $ xcrun --toolchain org.swift.59202403031a --find swiftc /Library/Developer/Toolchains/swift-DEVELOPMENT-SNAPSHOT-2024-03-03-a.xctoolchain/usr/bin/swiftc Swift Package Manager SwiftPM also respects the TOOLCHAINS variable, and it has a --toolchains parameter as well, but this one expects the path to the toolchain, not its bundle ID. Example: $ swift build --toolchain /Library/Developer/Toolchains/swift-latest.xctoolchain Missing toolchains are (silently) ignored Another thing to be aware of: if you specify a toolchain that isn’t installed (e.g. because of a typo or because you’re trying to run a script that was developed in a different environment), none of the tools will fail: swift, xcrun, and xcodebuild silently ignore the toolchain setting and use the default Swift toolchain (set via xcode-select). SwiftPM silently ignores a missing toolchain set via TOOLCHAINS. If you pass an invalid directory to the --toolchains parameter, it at least prints a warning before it continues building with the default toolchain. I don’t like this. I’d much rather get an error if the build tool can’t find the toolchain I told it to use. It’s especially dangerous in scripts.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            How the Swift compiler knows that DispatchQueue.main implies @MainActor

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              You may have noticed that the Swift compiler automatically treats the closure of a DispatchQueue.main.async call as @MainActor. In other words, we can call a main-actor-isolated function in the closure: import Dispatch @MainActor func mainActorFunc() { } DispatchQueue.main.async { // The compiler lets us call this because // it knows we're on the main actor. mainActorFunc() } This behavior is welcome and very convenient, but it bugs me that it’s so hidden. As far as I know it isn’t documented, and neither Xcode nor any other editor/IDE I’ve used do a good job of showing me the actor context a function or closure will run in, even though the compiler has this information. I’ve written about a similar case before in Where View.task gets its main-actor isolation from, where Swift/Xcode hide essential information from the programmer by not showing certain attributes in declarations or the documentation. It’s a syntax check So how is the magic behavior for DispatchQueue.main.async implemented? It can’t be an attribute or other annotation on the closure parameter of the DispatchQueue.async method because the actual queue instance isn’t known at that point. A bit of experimentation reveals that it is in fact a relatively coarse source-code-based check that singles out invocations on DispatchQueue.main, in exactly that spelling. For example, the following variations do produce warnings/errors (in Swift 5.10/6.0, respectively), even though they are just as safe as the previous code snippet. This is because we aren’t using the “correct” DispatchQueue.main.async spelling: let queue = DispatchQueue.main queue.async { // Error: Call to main actor-isolated global function // 'mainActorFunc()' in a synchronous nonisolated context mainActorFunc() // ❌ } typealias DP = DispatchQueue DP.main.async { // Error: Call to main actor-isolated global function // 'mainActorFunc()' in a synchronous nonisolated context mainActorFunc() // ❌ } I found the place in the Swift compiler source code where the check happens. In the compiler’s semantic analysis stage (called “Sema”; this is the phase right after parsing), the type checker calls a function named adjustFunctionTypeForConcurrency, passing in a Boolean it obtained from isMainDispatchQueueMember, which returns true if the source code literally references DispatchQueue.main. In that case, the type checker adds the @_unsafeMainActor attribute to the function type. Good to know. Fun fact: since this is a purely syntax-based check, if you define your own type named DispatchQueue, give it a static main property and a function named async that takes a closure, the compiler will apply the same “fix” to it. This is NOT recommended: // Define our own `DispatchQueue.main.async` struct DispatchQueue { static let main: Self = .init() func async(_ work: @escaping () -> Void) {} } // This calls our DispatchQueue.main.async { // No error! Compiler has inserted `@_unsafeMainActor` mainActorFunc() } Perplexity through obscurity I love that this automatic @MainActor inference for DispatchQueue.main exists. I do not love that it’s another piece of hidden, implicit behavior that makes Swift concurrency harder to learn. I want to see all the @_unsafeMainActor and @_unsafeInheritExecutor and @_inheritActorContext annotations! I believe Apple is doing the community a disservice by hiding these in Xcode. The biggest benefit of Swift’s concurrency model over what we had before is that so many things are statically known at compile time. It’s a shame that the compiler knows on which executor a particular line of code will run, but none of the tools seem to be able to show me this. Instead, I’m forced to hunt for @MainActor annotations and hidden attributes in superclasses, protocols, etc. This feels especially problematic during the Swift 5-to-6 transition phase we’re currently in where it’s so easy to misuse concurrency and not get a compiler error (and sometimes not even a warning if you forget to enable strict concurrency checking). The most impactful change Apple can make to make Swift concurrency less confusing is to show the inferred executor context for each line of code in Xcode. Make it really obvious what code runs on the main actor, some other actor, or the global cooperative pool. Use colors or whatnot! (Other Swift IDEs should do this too, of course. I’m just picking on Xcode because Apple has the most leverage.)

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              How the relative size modifier interacts with stack views

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                And what it can teach us about SwiftUI’s stack layout algorithm I have one more thing to say on the relative sizing view modifier from my previous post, Working with percentages in SwiftUI layout. I’m assuming you’ve read that article. The following is good to know if you want to use the modifier in your own code, but I hope you’ll also learn some general tidbits about SwiftUI’s layout algorithm for HStacks and VStacks. Using relative sizing inside a stack view Let’s apply the relativeProposed modifier to one of the subviews of an HStack: HStack(spacing: 10) { Color.blue .relativeProposed(width: 0.5) Color.green Color.yellow } .border(.primary) .frame(height: 80) What do you expect to happen here? Will the blue view take up 50 % of the available width? The answer is no. In fact, the blue rectangle becomes narrower than the others: This is because the HStack only proposes a proportion of its available width to each of its children. Here, the stack proposes one third of the available space to its first child, the relative sizing modifier. The modifier then halves this value, resulting in one sixth of the total width (minus spacing) for the blue color. The other two rectangles then become wider than one third because the first child view didn’t use up its full proposed width. Update May 1, 2024: SwiftUI’s built-in containerRelativeFrame modifier (introduced after I wrote my modifier) doesn’t exhibit this behavior because it uses the size of the nearest container view as its reference, and stack views don’t count as containers in this context (which I find somewhat unintuitive, but that’s the way it is). Order matters Now let’s move the modifier to the green color in the middle: HStack(spacing: 10) { Color.blue Color.green .relativeProposed(width: 0.5) Color.yellow } Naively, I’d expect an equivalent result: the green rectangle should become 100 pt wide, and blue and yellow should be 250 pt each. But that’s not what happens — the yellow view ends up being wider than the blue one: I found this unintuitive at first, but it makes sense if you understand that the HStack processes its children in sequence: The HStack proposes one third of its available space to the blue view: (620 – 20) / 3 = 200. The blue view accepts the proposal and becomes 200 pt wide. Next up is the relativeProposed modifier. The HStack divides the remaining space by the number of remaining subviews and proposes that: 400 / 2 = 200. Our modifier halves this proposal and proposes 100 pt to the green view, which accepts it. The modifier in turn adopts the size of its child and returns 100 pt to the HStack. Since the second subview used less space than proposed, the HStack now has 300 pt left over to propose to its final child, the yellow color. Important: the order in which the stack lays out its subviews happens to be from left to right in this example, but that’s not always the case. In general, HStacks and VStacks first group their subviews by layout priority (more on that below), and then order the views inside each group by flexibility such that the least flexible views are laid out first. For more on this, see How an HStack Lays out Its Children by Chris Eidhof. The views in our example are all equally flexible (they all can become any width between 0 and infinity), so the stack processes them in their “natural” order. Leftover space isn’t redistributed By now you may be able guess how the layout turns out when we move our view modifier to the last child view: HStack(spacing: 10) { Color.blue Color.green Color.yellow .relativeProposed(width: 0.5) } Blue and green each receive one third of the available width and become 200 pt wide. No surprises there. When the HStack reaches the relativeProposed modifier, it has 200 pt left to distribute. Again, the modifier and the yellow rectangle only use half of this amount. The end result is that the HStack ends up with 100 pt left over. The process stops here — the HStack does not start over in an attempt to find a “better” solution. The stack makes itself just big enough to contain its subviews (= 520 pt incl. spacing) and reports that size to its parent. Layout priority We can use the layoutPriority view modifier to influence how stacks and other containers lay out their children. Let’s give the subview with the relative sizing modifier a higher layout priority (the default priority is 0): HStack(spacing: 10) { Color.blue Color.green Color.yellow .relativeProposed(width: 0.5) .layoutPriority(1) } This results in a layout where the yellow rectangle actually takes up 50 % of the available space: Explanation: The HStack groups its children by layout priority and then processes each group in sequence, from highest to lowest priority. Each group is proposed the entire remaining space. The first layout group only contains a single view, our relative sizing modifier with the yellow color. The HStack proposes the entire available space (minus spacing) = 600 pt. Our modifier halves the proposal, resulting in 300 pt for the yellow view. There are 300 pt left over for the second layout group. These are distributed equally among the two children because each subview accepts the proposed size. Conclusion The code I used to generate the images in this article is available on GitHub. I only looked at HStacks here, but VStacks work in exactly the same way for the vertical dimension. SwiftUI’s layout algorithm always follows this basic pattern of proposed sizes and responses. Each of the built-in “primitive” views (e.g. fixed and flexible frames, stacks, Text, Image, Spacer, shapes, padding, background, overlay) has a well-defined (if not always well-documented) layout behavior that can be expressed as a function (ProposedViewSize) -> CGSize. You’ll need to learn the behavior for view to work effectively with SwiftUI. A concrete lesson I’m taking away from this analysis: HStack and VStack don’t treat layout as an optimization problem that tries to find the optimal solution for a set of constraints (autolayout style). Rather, they sort their children in a particular way and then do a single proposal-and-response pass over them. If there’s space leftover at the end, or if the available space isn’t enough, then so be it.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                Working with percentages in SwiftUI layout

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  SwiftUI’s layout primitives generally don’t provide relative sizing options, e.g. “make this view 50 % of the width of its container”. Let’s build our own! Use case: chat bubbles Consider this chat conversation view as an example of what I want to build. The chat bubbles always remain 80 % as wide as their container as the view is resized: The chat bubbles should become 80 % as wide as their container. Download video Building a proportional sizing modifier 1. The Layout We can build our own relative sizing modifier on top of the Layout protocol. The layout multiplies its own proposed size (which it receives from its parent view) with the given factors for width and height. It then proposes this modified size to its only subview. Here’s the implementation (the full code, including the demo app, is on GitHub): /// A custom layout that proposes a percentage of its /// received proposed size to its subview. /// /// - Precondition: must contain exactly one subview. fileprivate struct RelativeSizeLayout: Layout { var relativeWidth: Double var relativeHeight: Double func sizeThatFits( proposal: ProposedViewSize, subviews: Subviews, cache: inout () ) -> CGSize { assert(subviews.count == 1, "expects a single subview") let resizedProposal = ProposedViewSize( width: proposal.width.map { $0 * relativeWidth }, height: proposal.height.map { $0 * relativeHeight } ) return subviews[0].sizeThatFits(resizedProposal) } func placeSubviews( in bounds: CGRect, proposal: ProposedViewSize, subviews: Subviews, cache: inout () ) { assert(subviews.count == 1, "expects a single subview") let resizedProposal = ProposedViewSize( width: proposal.width.map { $0 * relativeWidth }, height: proposal.height.map { $0 * relativeHeight } ) subviews[0].place( at: CGPoint(x: bounds.midX, y: bounds.midY), anchor: .center, proposal: resizedProposal ) } } Notes: I made the type private because I want to control how it can be used. This is important for maintaining the assumption that the layout only ever has a single subview (which makes the math much simpler). Proposed sizes in SwiftUI can be nil or infinity in either dimension. Our layout passes these special values through unchanged (infinity times a percentage is still infinity). I’ll discuss below what implications this has for users of the layout. 2. The View extension Next, we’ll add an extension on View that uses the layout we just wrote. This becomes our public API: extension View { /// Proposes a percentage of its received proposed size to `self`. public func relativeProposed(width: Double = 1, height: Double = 1) -> some View { RelativeSizeLayout(relativeWidth: width, relativeHeight: height) { // Wrap content view in a container to make sure the layout only // receives a single subview. Because views are lists! VStack { // alternatively: `_UnaryViewAdaptor(self)` self } } } } Notes: I decided to go with a verbose name, relativeProposed(width:height:), to make the semantics clear: we’re changing the proposed size for the subview, which won’t always result in a different actual size. More on this below. We’re wrapping the subview (self in the code above) in a VStack. This might seem redundant, but it’s necessary to make sure the layout only receives a single element in its subviews collection. See Chris Eidhof’s SwiftUI Views are Lists for an explanation. Usage The layout code for a single chat bubble in the demo video above looks like this: let alignment: Alignment = message.sender == .me ? .trailing : .leading chatBubble .relativeProposed(width: 0.8) .frame(maxWidth: .infinity, alignment: alignment) The outermost flexible frame with maxWidth: .infinity is responsible for positioning the chat bubble with leading or trailing alignment, depending on who’s speaking. You can even add another frame that limits the width to a maximum, say 400 points: let alignment: Alignment = message.sender == .me ? .trailing : .leading chatBubble .frame(maxWidth: 400) .relativeProposed(width: 0.8) .frame(maxWidth: .infinity, alignment: alignment) Here, our relative sizing modifier only has an effect as the bubbles become narrower than 400 points. In a wider window the width-limiting frame takes precedence. I like how composable this is! Download video 80 % won’t always result in 80 % If you watch the debugging guides I’m drawing in the video above, you’ll notice that the relative sizing modifier never reports a width greater than 400, even if the window is wide enough: The relative sizing modifier accepts the actual size of its subview as its own size. This is because our layout only adjusts the proposed size for its subview but then accepts the subview’s actual size as its own. Since SwiftUI views always choose their own size (which the parent can’t override), the subview is free to ignore our proposal. In this example, the layout’s subview is the frame(maxWidth: 400) view, which sets its own width to the proposed width or 400, whichever is smaller. Understanding the modifier’s behavior Proposed size ≠ actual size It’s important to internalize that the modifier works on the basis of proposed sizes. This means it depends on the cooperation of its subview to achieve its goal: views that ignore their proposed size will be unaffected by our modifier. I don’t find this particularly problematic because SwiftUI’s entire layout system works like this. Ultimately, SwiftUI views always determine their own size, so you can’t write a modifier that “does the right thing” (whatever that is) for an arbitrary subview hierarchy. nil and infinity I already mentioned another thing to be aware of: if the parent of the relative sizing modifier proposes nil or .infinity, the modifier will pass the proposal through unchanged. Again, I don’t think this is particularly bad, but it’s something to be aware of. Proposing nil is SwiftUI’s way of telling a view to become its ideal size (fixedSize does this). Would you ever want to tell a view to become, say, 50 % of its ideal width? I’m not sure. Maybe it’d make sense for resizable images and similar views. By the way, you could modify the layout to do something like this: If the proposal is nil or infinity, forward it to the subview unchanged. Take the reported size of the subview as the new basis and apply the scaling factors to that size (this still breaks down if the child returns infinity). Now propose the scaled size to the subview. The subview might respond with a different actual size. Return this latest reported size as your own size. This process of sending multiple proposals to child views is called probing. Lots of built-in containers views do this too, e.g. VStack and HStack. Nesting in other container views The relative sizing modifier interacts in an interesting way with stack views and other containers that distribute the available space among their children. I thought this was such an interesting topic that I wrote a separate article about it: How the relative size modifier interacts with stack views. The code The complete code is available in a Gist on GitHub. Digression: Proportional sizing in early SwiftUI betas The very first SwiftUI betas in 2019 did include proportional sizing modifiers, but they were taken out before the final release. Chris Eidhof preserved a copy of SwiftUI’s “header file” from that time that shows their API, including quite lengthy documentation. I don’t know why these modifiers didn’t survive the beta phase. The release notes from 2019 don’t give a reason: The relativeWidth(_:), relativeHeight(_:), and relativeSize(width:height:) modifiers are deprecated. Use other modifiers like frame(minWidth:idealWidth:maxWidth:minHeight:idealHeight:maxHeight:alignment:) instead. (51494692) I also don’t remember how these modifiers worked. They probably had somewhat similar semantics to my solution, but I can’t be sure. The doc comments linked above sound straightforward (“Sets the width of this view to the specified proportion of its parent’s width.”), but they don’t mention the intricacies of the layout algorithm (proposals and responses) at all. containerRelativeFrame Update May 1, 2024: Apple introduced the containerRelativeFrame modifier for its 2023 OSes (iOS 17/macOS 14). If your deployment target permits it, this can be a good, built-in alternative. Note that containerRelativeFrame behaves differently than my relativeProposed modifier as it computes the size relative to the nearest container view, whereas my modifier uses its proposed size as the reference. The SwiftUI documentation somewhat vaguely lists the views that count as a container for containerRelativeFrame. Notably, stack views don’t count! Check out Jordan Morgan’s article Modifier Monday: .containerRelativeFrame(_ axes:) (2022-06-26) to learn more about containerRelativeFrame.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  Keyboard shortcuts for Export Unmodified Original in Photos for Mac

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    Problem The Photos app on macOS doesn’t provide a keyboard shortcut for the Export Unmodified Original command. macOS allows you to add your own app-specific keyboard shortcuts via System Settings > Keyboard > Keyboard Shortcuts > App Shortcuts. You need to enter the exact spelling of the menu item you want to invoke. Photos renames the command depending on what’s selected: Export Unmodified Original For 1 Photo“ turns into ”… Originals For 2 Videos” turns into “… For 3 Items” (for mixed selections), and so on. Argh! The System Settings UI for assigning keyboard shortcuts is extremely tedious to use if you want to add more than one or two shortcuts. Dynamically renaming menu commands is cute, but it becomes a problem when you want to assign keyboard shortcuts. Solution: shell script Here’s a Bash script1 that assigns Ctrl + Opt + Cmd + E to Export Unmodified Originals for up to 20 selected items: #!/bin/bash # Assigns a keyboard shortcut to the Export Unmodified Originals # menu command in Photos.app on macOS. # @ = Command # ^ = Control # ~ = Option # $ = Shift shortcut='@~^e' # Set shortcut for 1 selected item echo "Setting shortcut for 1 item" defaults write com.apple.Photos NSUserKeyEquivalents -dict-add "Export Unmodified Original For 1 Photo" "$shortcut" defaults write com.apple.Photos NSUserKeyEquivalents -dict-add "Export Unmodified Original For 1 Video" "$shortcut" # Set shortcut for 2-20 selected items objects=(Photos Videos Items) for i in {2..20} do echo "Setting shortcut for $i items" for object in "${objects[@]}" do defaults write com.apple.Photos NSUserKeyEquivalents -dict-add "Export Unmodified Originals For $i $object" "$shortcut" done done # Use this command to verify the result: # defaults read com.apple.Photos NSUserKeyEquivalents The script is also available on GitHub. Usage: Quit Photos.app. Run the script. Feel free to change the key combo or count higher than 20. Open Photos.app. Note: There’s a bug in Photos.app on macOS 13.2 (and at least some earlier versions). Custom keyboard shortcuts don’t work until you’ve opened the menu of the respective command at least once. So you must manually open the File > Export once before the shortcut will work. (For Apple folks: FB11967573.) I still write Bash scripts because Shellcheck doesn’t support Zsh. ↩︎

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    Swift Evolution proposals in Alfred

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      I rarely participate actively in the Swift Evolution process, but I frequently refer to evolution proposals for my work, often multiple times per week. The proposals aren’t always easy to read, but they’re the most comprehensive (and sometimes only) documentation we have for many Swift features. For years, my tool of choice for searching Swift Evolution proposals has been Karoy Lorentey’s swift-evolution workflow for Alfred. The workflow broke recently due to data format changes. Karoy was kind enough to add me as a maintainer so I could fix it. The new version 2.1.0 is now available on GitHub. Download the .alfredworkflow file and double-click to install. Besides the fix, the update has a few other improvements: The proposal title is now displayed more prominently. New actions to copy the proposal title (hold down Command) or copy it as a Markdown link (hold down Shift + Command). The script forwards the main metadata of the selected proposal (id, title, status, URL) to Alfred. If you want to extend the workflow with your own actions, you can refer to these variables.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      Pattern matching on error codes

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        Foundation overloads the pattern matching operator ~= to enable matching against error codes in catch clauses. catch clauses in Swift support pattern matching, using the same patterns you’d use in a case clause inside a switch or in an if case … statement. For example, to handle a file-not-found error you might write: import Foundation do { let fileURL = URL(filePath: "/abc") // non-existent file let data = try Data(contentsOf: fileURL) } catch let error as CocoaError where error.code == .fileReadNoSuchFile { print("File doesn't exist") } catch { print("Other error: \(error)") } This binds a value of type CocoaError to the variable error and then uses a where clause to check the specific error code. However, if you don’t need access to the complete error instance, there’s a shorter way to write this, matching directly against the error code: let data = try Data(contentsOf: fileURL) - } catch let error as CocoaError where error.code == .fileReadNoSuchFile { + } catch CocoaError.fileReadNoSuchFile { print("File doesn't exist") Foundation overloads ~= I was wondering why this shorter syntax works. Is there some special compiler magic for pattern matching against error codes of NSError instances? Turns out: no, the answer is much simpler. Foundation includes an overload for the pattern matching operator ~= that matches error values against error codes.1 The implementation looks something like this: public func ~= (code: CocoaError.Code, error: any Error) -> Bool { guard let error = error as? CocoaError else { return false } return error.code == code } The actual code in Foundation is a little more complex because it goes through a hidden protocol named _ErrorCodeProtocol, but that’s not important. You can check out the code in the Foundation repository: Darwin version, swift-corelibs-foundation version. This matching on error codes is available for CocoaError, URLError, POSIXError, and MachError (and possibly more types in other Apple frameworks, I haven’t checked). I wrote about the ~= operator before, way back in 2015(!): Pattern matching in Swift and More pattern matching examples. ↩︎

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        You should watch Double Fine Adventure

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          I know I’m almost a decade late to this party, but I’m probably not the only one, so here goes. Double Fine Adventure was a wildly successful 2012 Kickstarter project to crowdfund the development of a point-and-click adventure game and, crucially, to document its development on video. The resulting game Broken Age was eventually released in two parts in 2014 and 2015. Broken Age is a beautiful game and I recommend you try it. It’s available for lots of platforms and is pretty cheap (10–15 euros/dollars or less). I played it on the Nintendo Switch, which worked very well. Broken Age. But the real gem to me was watching the 12.5-hour documentary on YouTube. A video production team followed the entire three-year development process from start to finish. It provides a refreshingly candid and transparent insight into “how the sausage is made”, including sensitive topics such as financial problems, layoffs, and long work hours. Throughout all the ups and downs there’s a wonderful sense of fun and camaraderie among the team at Double Fine, which made watching the documentary even more enjoyable to me than playing Broken Age. You can tell these people love working with each other. I highly recommend taking a look if you find this mildly interesting. The Double Fine Adventure documentary. The first major game spoilers don’t come until episode 15, so you can safely watch most of the documentary before playing the game (and this is how the original Kickstarter backers experienced it). However, I think it’s even more interesting to play the game first, or to experience both side-by-side. My suggestion: watch two or three episodes of the documentary. If you like it, start playing Broken Age alongside it.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          Understanding SwiftUI view lifecycles

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            I wrote an app called SwiftUI View Lifecycle. The app allows you to observe how different SwiftUI constructs and containers affect a view’s lifecycle, including the lifetime of its state and when onAppear gets called. The code for the app is on GitHub. It can be built for iOS and macOS. The view tree and the render tree When we write SwiftUI code, we construct a view tree that consists of nested view values. Instances of the view tree are ephemeral: SwiftUI constantly destroys and recreates (parts of) the view tree as it processes state changes. The view tree serves as a blueprint from which SwiftUI creates a second tree, which represents the actual view “objects” that are “on screen” at any given time (the “objects” could be actual UIView or NSView objects, but also other representations; the exact meaning of “on screen” can vary depending on context). Chris Eidhof likes to call this second tree the render tree (the link points to a 3 minute video where Chris demonstrates this duality, highly recommended). The render tree persists across state changes and is used by SwiftUI to establish view identity. When a state change causes a change in a view’s value, SwiftUI will find the corresponding view object in the render tree and update it in place, rather than recreating a new view object from scratch. This is of course key to making SwiftUI efficient, but the render tree has another important function: it controls the lifetimes of views and their state. View lifecycles and state We can define a view’s lifetime as the timespan it exists in the render tree. The lifetime begins with the insertion into the render tree and ends with the removal. Importantly, the lifetime extends to view state defined with @State and @StateObject: when a view gets removed from the render tree, its state is lost; when the view gets inserted again later, the state will be recreated with its initial value. The SwiftUI View Lifecycle app tracks three lifecycle events for a view and displays them as timestamps: @State = when the view’s state was created (equivalent to the start of the view’s lifetime) onAppear = when onAppear was last called onDisappear = when onDisappear was last called The lifecycle monitor view displays the timestamps when certain lifecycle events last occurred. The app allows you to observe these events in different contexts. As you click your way through the examples, you’ll notice that the timing of these events changes depending on the context a view is embedded in. For example: An if/else statement creates and destroys its child views every time the condition changes; state is not preserved. A ScrollView eagerly inserts all of its children into the render tree, regardless of whether they’re inside the viewport or not. All children appear right away and never disappear. A List with dynamic content (using ForEach) lazily inserts only the child views that are currently visible. But once a child view’s lifetime has started, the list will keep its state alive even when it gets scrolled offscreen again. onAppear and onDisappear get called repeatedly as views are scrolled into and out of the viewport. A NavigationStack calls onAppear and onDisappear as views are pushed and popped. State for parent levels in the stack is preserved when a child view is pushed. A TabView starts the lifetime of all child views right away, even the non-visible tabs. onAppear and onDisappear get called repeatedly as the user switches tabs, but the tab view keeps the state alive for all tabs. Lessons Here are a few lessons to take away from this: Different container views may have different performance and memory usage behaviors, depending on how long they keep child views alive. onAppear isn’t necessarily called when the state is created. It can happen later (but never earlier). onAppear can be called multiple times in some container views. If you need a side effect to happen exactly once in a view’s lifetime, consider writing yourself an onFirstAppear helper, as shown by Ian Keen and Jordan Morgan in Running Code Only Once in SwiftUI (2022-11-01). I’m sure you’ll find more interesting tidbits when you play with the app. Feedback is welcome!

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            clipped() doesn’t affect hit testing

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              The clipped() modifier in SwiftUI clips a view to its bounds, hiding any out-of-bounds content. But note that clipping doesn’t affect hit testing; the clipped view can still receive taps/clicks outside the visible area. I tested this on iOS 16.1 and macOS 13.0. Example Here’s a 300×300 square, which we then constrain to a 100×100 frame. I also added a border around the outer frame to visualize the views: Rectangle() .fill(.orange.gradient) .frame(width: 300, height: 300) // Set view to 100×100 → renders out of bounds .frame(width: 100, height: 100) .border(.blue) SwiftUI views don’t clip their content by default, hence the full 300×300 square remains visible. Notice the blue border that indicates the 100×100 outer frame: Now let’s add .clipped() to clip the large square to the 100×100 frame. I also made the square tappable and added a button: VStack { Button("You can't tap me!") { buttonTapCount += 1 } .buttonStyle(.borderedProminent) Rectangle() .fill(.orange.gradient) .frame(width: 300, height: 300) .frame(width: 100, height: 100) .clipped() .onTapGesture { rectTapCount += 1 } } When you run this code, you’ll discover that the button isn’t tappable at all. This is because the (unclipped) square, despite not being fully visible, obscures the button and “steals” all taps. The dashed outline indicates the hit area of the orange square. The button isn’t tappable because it’s covered by the clipped view with respect to hit testing. The fix: .contentShape() The contentShape(_:) modifier defines the hit testing area for a view. By adding .contentShape(Rectangle()) to the 100×100 frame, we limit hit testing to that area, making the button tappable again: Rectangle() .fill(.orange.gradient) .frame(width: 300, height: 300) .frame(width: 100, height: 100) .contentShape(Rectangle()) .clipped() Note that the order of .contentShape(Rectangle()) and .clipped() could be swapped. The important thing is that contentShape is an (indirect) parent of the 100×100 frame modifier that defines the size of the hit testing area. Video demo I made a short video that demonstrates the effect: Initially, taps on the button, or even on the surrounding whitespace, register as taps on the square. The top switch toggles display of the square before clipping. This illustrates its hit testing area. The second switch adds .contentShape(Rectangle()) to limit hit testing to the visible area. Now tapping the button increments the button’s tap count. The full code for this demo is available on GitHub. Download video Summary The clipped() modifier doesn’t affect the clipped view’s hit testing region. The same is true for clipShape(_:). It’s often a good idea to combine these modifiers with .contentShape(Rectangle()) to bring the hit testing logic in sync with the UI.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              When .animation animates more (or less) than it’s supposed to

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                On the positioning of the .animation modifier in the view tree, or: “Rendering” vs. “non-rendering” view modifiers The documentation for SwiftUI’s animation modifier says: Applies the given animation to this view when the specified value changes. This sounds unambiguous to me: it sets the animation for “this view”, i.e. the part of the view tree that .animation is being applied to. This should give us complete control over which modifiers we want to animate, right? Unfortunately, it’s not that simple: it’s easy to run into situations where a view change inside an animated subtree doesn’t get animated, or vice versa. Unsurprising examples Let me give you some examples, starting with those that do work as documented. I tested all examples on iOS 16.1 and macOS 13.0. 1. Sibling views can have different animations Independent subtrees of the view tree can be animated independently. In this example we have three sibling views, two of which are animated with different durations, and one that isn’t animated at all: struct Example1: View { var flag: Bool var body: some View { HStack(spacing: 40) { Rectangle() .frame(width: 80, height: 80) .foregroundColor(.green) .scaleEffect(flag ? 1 : 1.5) .animation(.easeOut(duration: 0.5), value: flag) Rectangle() .frame(width: 80, height: 80) .foregroundColor(flag ? .yellow : .red) .rotationEffect(flag ? .zero : .degrees(45)) .animation(.easeOut(duration: 2.0), value: flag) Rectangle() .frame(width: 80, height: 80) .foregroundColor(flag ? .pink : .mint) } } } The two animation modifiers each apply to their own subtree. They don’t interfere with each other and have no effect on the rest of the view hierarchy: Download video 2. Nested animation modifiers When two animation modifiers are nested in a single view tree such that one is an indirect parent of the other, the inner modifier can override the outer animation for its subviews. The outer animation applies to view modifiers that are placed between the two animation modifiers. In this example we have one rectangle view with animated scale and rotation effects. The outer animation applies to the entire subtree, including both effects. The inner animation modifier overrides the outer animation only for what’s nested below it in the view tree, i.e. the scale effect: struct Example2: View { var flag: Bool var body: some View { Rectangle() .frame(width: 80, height: 80) .foregroundColor(.green) .scaleEffect(flag ? 1 : 1.5) .animation(.default, value: flag) // inner .rotationEffect(flag ? .zero : .degrees(45)) .animation(.default.speed(0.3), value: flag) // outer } } As a result, the scale and rotation changes animate at different speeds: Download video Note that we could also pass .animation(nil, value: flag) to selectively disable animations for a subtree, overriding a non-nil animation further up the view tree. 3. animation only animates its children (with exceptions) As a general rule, the animation modifier only applies to its subviews. In other words, views and modifiers that are direct or indirect parents of an animation modifier should not be animated. As we’ll see below, it doesn’t always work like that, but here’s an example where it does. This is a slight variation of the previous code snippet where I removed the outer animation modifier (and changed the color for good measure): struct Example3: View { var flag: Bool var body: some View { Rectangle() .frame(width: 80, height: 80) .foregroundColor(.orange) .scaleEffect(flag ? 1 : 1.5) .animation(.default, value: flag) // Don't animate the rotation .rotationEffect(flag ? .zero : .degrees(45)) } } Recall that the order in which view modifiers are written in code is inverted with respect to the actual view tree hierarchy. Each view modifier is a new view that wraps the view it’s being applied to. So in our example, the scale effect is the child of the animation modifier, whereas the rotation effect is its parent. Accordingly, only the scale change gets animated: Download video Surprising examples Now it’s time for the “fun” part. It turns out not all view modifiers behave as intuitively as scaleEffect and rotationEffect when combined with the animation modifier. 4. Some modifiers don’t respect the rules In this example we’re changing the color, size, and alignment of the rectangle. Only the size change should be animated, which is why we’ve placed the alignment and color mutations outside the animation modifier: struct Example4: View { var flag: Bool var body: some View { let size: CGFloat = flag ? 80 : 120 Rectangle() .frame(width: size, height: size) .animation(.default, value: flag) .frame(maxWidth: .infinity, alignment: flag ? .leading : .trailing) .foregroundColor(flag ? .pink : .indigo) } } Unfortunately, this doesn’t work as intended, as all three changes are animated: Download video It behaves as if the animation modifier were the outermost element of this view subtree. 5. padding and border This one’s sort of the inverse of the previous example because a change we want to animate doesn’t get animated. The padding is a child of the animation modifier, so I’d expect changes to it to be animated, i.e. the border should grow and shrink smoothly: struct Example5: View { var flag: Bool var body: some View { Rectangle() .frame(width: 80, height: 80) .padding(flag ? 20 : 40) .animation(.default, value: flag) .border(.primary) .foregroundColor(.cyan) } } But that’s not what happens: Download video 6. Font modifiers Font modifiers also behave seemingly erratic with respect to the animation modifier. In this example, we want to animate the font width, but not the size or weight (smooth text animation is a new feature in iOS 16): struct Example6: View { var flag: Bool var body: some View { Text("Hello!") .fontWidth(flag ? .condensed : .expanded) .animation(.default, value: flag) .font(.system( size: flag ? 40 : 60, weight: flag ? .regular : .heavy) ) } } You guessed it, this doesn’t work as intended. Instead, all text properties animate smoothly: Download video Why does it work like this? In summary, the placement of the animation modifier in the view tree allows some control over which changes get animated, but it isn’t perfect. Some modifiers, such as scaleEffect and rotationEffect, behave as expected, whereas others (frame, padding, foregroundColor, font) are less controllable. I don’t fully understand the rules, but the important factor seems to be if a view modifier actually “renders” something or not. For instance, foregroundColor just writes a color into the environment; the modifier itself doesn’t draw anything. I suppose this is why its position with respect to animation is irrelevant: RoundedRectangle(cornerRadius: flag ? 0 : 40) .animation(.default, value: flag) // Color change still animates, even though we’re outside .animation .foregroundColor(flag ? .pink : .indigo) The rendering presumably takes place on the level of the RoundedRectangle, which reads the color from the environment. At this point the animation modifier is active, so SwiftUI will animate all changes that affect how the rectangle is rendered, regardless of where in the view tree they’re coming from. The same explanation makes intuitive sense for the font modifiers in example 6. The actual rendering, and therefore the animation, occurs on the level of the Text view. The various font modifiers affect how the text is drawn, but they don’t render anything themselves. Similarly, padding and frame (including the frame’s alignment) are “non-rendering” modifiers too. They don’t use the environment, but they influence the layout algorithm, which ultimately affects the size and position of one or more “rendering” views, such as the rectangle in example 4. That rectangle sees a combined change in its geometry, but it can’t tell where the change came from, so it’ll animate the full geometry change. In example 5, the “rendering” view that’s affected by the padding change is the border (which is implemented as a stroked rectangle in an overlay). Since the border is a parent of the animation modifier, its geometry change is not animated. In contrast to frame and padding, scaleEffect and rotationEffect are “rendering” modifiers. They apparently perform the animations themselves. Conclusion SwiftUI views and view modifiers can be divided into “rendering“ and “non-rendering” groups (I wish I had better terms for these). In iOS 16/macOS 13, the placement of the animation modifier with respect to non-rendering modifiers is irrelevant for deciding if a change gets animated or not. Non-rendering modifiers include (non-exhaustive list): Layout modifiers (frame, padding, position, offset) Font modifiers (font, bold, italic, fontWeight, fontWidth) Other modifiers that write data into the environment, e.g. foregroundColor, foregroundStyle, symbolRenderingMode, symbolVariant Rendering modifiers include (non-exhaustive list): clipShape, cornerRadius Geometry effects, e.g. scaleEffect, rotationEffect, projectionEffect Graphical effects, e.g. blur, brightness, hueRotation, opacity, saturation, shadow

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                Xcode 14.0 generates wrong concurrency code for macOS targets

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  Mac apps built with Xcode 14.0 and 14.0.1 may contain concurrency bugs because the Swift 5.7 compiler can generate invalid code when targeting the macOS 12.3 SDK. If you distribute Mac apps, you should build them with Xcode 13.4.1 until Xcode 14.1 is released. Here’s what happened: Swift 5.7 implements SE-0338: Clarify the Execution of Non-Actor-Isolated Async Functions, which introduces new rules how async functions hop between executors. Because of SE-0338, when compiling concurrency code, the Swift 5.7 compiler places executor hops in different places than Swift 5.6. Some standard library functions need to opt out of the new rules. They are annotated with a new, unofficial attribute @_unsafeInheritExecutor, which was introduced for this purpose. When the Swift 5.7 compiler sees this attribute, it generates different executor hops. The attribute is only present in the Swift 5.7 standard library, i.e. in the iOS 16 and macOS 13 SDKs. This is fine for iOS because compiler version and the SDK’s standard library version match in Xcode 14.0. But for macOS targets, Xcode 14.0 uses the Swift 5.7 compiler with the standard library from Swift 5.6, which doesn’t contain the @_unsafeInheritExecutor attribute. This is what causes the bugs. Note that the issue is caused purely by the version mismatch at compile-time. The standard library version used by the compiled app at run-time (which depends on the OS version the app runs on) isn’t relevant. As soon as Xcode 14.1 gets released with the macOS 13 SDK, the version mismatch will go away, and Mac targets built with Xcode 14.1 won’t exhibit these bugs. Third-party developers had little chance of discovering the bug during the Xcode 14.0 beta phase because the betas ship with the new beta macOS SDK. The version mismatch occurs when the final Xcode release in September reverts back to the old macOS SDK to accommodate the different release schedules of iOS and macOS. Sources Breaking concurrency invariants is a serious issue, though I’m not sure how much of a problem this is in actual production apps. Here are all related bug reports that I know of: Concurrency is broken in Xcode 14 for macOS (2022-09-14) withUnsafeContinuation can break actor isolation (2022-10-07) And explanations of the cause from John McCall of the Swift team at Apple: John McCall (2022-10-07): This guarantee is unfortunately broken with Xcode 14 when compiling for macOS because it’s shipping with an old macOS SDK that doesn’t declare that withUnsafeContinuation inherits its caller’s execution context. And yes, there is a related actor-isolation issue because of this bug. That will be fixed by the release of the new macOS SDK. John McCall (2022-10-07): Now, there is a bug in Xcode 14 when compiling for the macOS SDK because it ships with an old SDK. That bug doesn’t actually break any of the ordering properties above. It does, however, break Swift’s data isolation guarantees because it causes withUnsafeContinuation, when called from an actor-isolated context, to send a non-Sendable function to a non-isolated executor and then call it, which is completely against the rules. And in fact, if you turn strict sendability checking on when compiling against that SDK, you will get a diagnostic about calling withUnsafeContinuation because it thinks that you’re violating the rules (because withUnsafeContinuation doesn’t properly inherit the execution context of its caller). Poor communication from Apple What bugs me most about the situation is Apple’s poor communication. When the official, current release of your programming language ships with a broken compiler for one of your most important platforms, the least I’d expect is a big red warning at the top of the release notes. I can’t find any mention of this issue in the Xcode 14.0 release notes or Xcode 14.0.1 release notes, however. Even better: the warning should be displayed prominently in Xcode, or Xcode 14.0 should outright refuse to build Mac apps. I’m sure the latter option isn’t practical for all sorts of reasons, although it sounds logical to me: if the only safe compiler/SDK combinations are either 5.6 with the macOS 12 SDK or 5.7 with the macOS 13 SDK, there shouldn’t be an official Xcode version that combines the 5.7 compiler with the macOS 12 SDK.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  Where View.task gets its main-actor isolation from

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    SwiftUI’s .task modifier inherits its actor context from the surrounding function. If you call .task inside a view’s body property, the async operation will run on the main actor because View.body is (semi-secretly) annotated with @MainActor. However, if you call .task from a helper property or function that isn’t @MainActor-annotated, the async operation will run in the cooperative thread pool. Example Here’s an example. Notice the two .task modifiers in body and helperView. The code is identical in both, yet only one of them compiles — in helperView, the call to a main-actor-isolated function fails because we’re not on the main actor in that context: We can call a main-actor-isolated function from inside body, but not from a helper property. import SwiftUI @MainActor func onMainActor() { print("on MainActor") } struct ContentView: View { var body: some View { VStack { helperView Text("in body") .task { // We can call a @MainActor func without await onMainActor() } } } var helperView: some View { Text("in helperView") .task { // ❗️ Error: Expression is 'async' but is not marked with 'await' onMainActor() } } } Why does it work like this? This behavior is caused by two (semi-)hidden annotations in the SwiftUI framework: The View protocol annotates its body property with @MainActor. This transfers to all conforming types. View.task annotates its action parameter with @_inheritActorContext, causing it to adopt the actor context from its use site. Sadly, none of these annotations are visible in the SwiftUI documentation, making it very difficult to understand what’s going on. The @MainActor annotation on View.body is present in Xcode’s generated Swift interface for SwiftUI (Jump to Definition of View), but that feature doesn’t work reliably for me, and as we’ll see, it doesn’t show the whole truth, either. View.body is annotated with @MainActor in Xcode’s generated interface for SwiftUI. SwiftUI’s module interface To really see the declarations the compiler sees, we need to look at SwiftUI’s module interface file. A module interface is like a header file for Swift modules. It lists the module’s public declarations and even the implementations of inlinable functions. Module interfaces use normal Swift syntax and have the .swiftinterface file extension. SwiftUI’s module interface is located at: [Path to Xcode.app]/Contents/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS.sdk/System/Library/Frameworks/SwiftUI.framework/Modules/SwiftUI.swiftmodule/arm64e-apple-ios.swiftinterface (There can be multiple .swiftinterface files in that directory, one per CPU architecture. Pick any one of them. Pro tip for viewing the file in Xcode: Editor > Syntax Coloring > Swift enables syntax highlighting.) Inside, you’ll find that View.body has the @MainActor(unsafe) attribute: @available(iOS 13.0, macOS 10.15, tvOS 13.0, watchOS 6.0, *) @_typeEraser(AnyView) public protocol View { // … @SwiftUI.ViewBuilder @_Concurrency.MainActor(unsafe) var body: Self.Body { get } } And you’ll find this declaration for .task, including the @_inheritActorContext attribute: @available(iOS 15.0, macOS 12.0, tvOS 15.0, watchOS 8.0, *) extension SwiftUI.View { #if compiler(>=5.3) && $AsyncAwait && $Sendable && $InheritActorContext @inlinable public func task( priority: _Concurrency.TaskPriority = .userInitiated, @_inheritActorContext _ action: @escaping @Sendable () async -> Swift.Void ) -> some SwiftUI.View { modifier(_TaskModifier(priority: priority, action: action)) } #endif // … } SwiftUI’s module interface file shows the @_inheritActorContext annotatation on View.task. Putting it all together Armed with this knowledge, everything makes more sense: When used inside body, task inherits the @MainActor context from body. When used outside of body, there is no implicit @MainActor annotation, so task will run its operation on the cooperative thread pool by default. Unless the view contains an @ObservedObject or @StateObject property, which makes the entire view @MainActor via this obscure rule for property wrappers whose wrappedValue property is bound to a global actor: A struct or class containing a wrapped instance property with a global actor-qualified wrappedValue infers actor isolation from that property wrapper Update May 1, 2024: SE-0401: Remove Actor Isolation Inference caused by Property Wrappers removes the above rule when compiling in Swift 6 language mode. This is a good change because it makes reasoning about actor isolation simpler. In the Swift 5 language mode, you can opt into the better behavior with the -enable-upcoming-feature DisableOutwardActorInference compiler flags. I recommend you do. The lesson: if you use helper properties or functions in your view, consider annotating them with @MainActor to get the same semantics as body. By the way, note that the actor context only applies to code that is placed directly inside the async closure, as well as to synchronous functions the closure calls. Async functions choose their own execution context, so any call to an async function can switch to a different executor. For example, if you call URLSession.data(from:) inside a main-actor-annotated function, the runtime will hop to the global cooperative executor to execute that method. See SE-0338: Clarify the Execution of Non-Actor-Isolated Async Functions for the precise rules. On Apple’s policy to hide annotations in documentation I understand Apple’s impetus not to show unofficial API or language features in the documentation lest developers get the preposterous idea to use these features in their own code! But it makes understanding so much harder. Before I saw the annotations in the .swiftinterface file, the behavior of the code at the beginning of this article never made sense to me. Hiding the details makes things seem like magic when they actually aren’t. And that’s not good, either.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    Experimenting with Live Activities

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      iOS 16 beta 4 is the first SDK release that supports Live Activities. A Live Activity is a widget-like view an app can place on your lock screen and update in real time. Examples where this can be useful include live sports scores or train departure times. These are my notes on playing with the API and implementing my first Live Activity. A bike computer on your lock screen My Live Activity is a display for a bike computer that I’ve been developing with a group a friends. Here’s a video of it in action: Download video And here with simulated data: Download video I haven’t talked much about our bike computer project publicly yet; that will hopefully change someday. In short, a group of friends and I designed a little box that connects to your bike’s hub dynamo, measures speed and distance, and sends the data via Bluetooth to an iOS app. The app records all your rides and can also act as a live speedometer when mounted on your bike’s handlebar. It’s this last feature that I wanted to replicate in the Live Activity. Follow Apple’s guide Adding a Live Activity to the app wasn’t hard. I found Apple’s guide Displaying live data on the Lock Screen with Live Activities easy to follow and quite comprehensive. No explicit user approval iOS doesn’t ask the user for approval when an app wants to show a Live Activity. I found this odd since it seems to invite developers to abuse the feature, but maybe it’s OK because of the foreground requirement (see below). Plus, users can disallow Live Activities on a per-app basis in Settings. Users can dismiss an active Live Activity from the lock screen by swiping (like a notification). Most apps will probably need to ask the user for notification permissions to update their Live Activities. The app must be in the foreground to start an activity To start a Live Activity, an app must be open in the foreground. This isn’t ideal for the bike computer because the speedometer can’t appear magically on the lock screen when the user starts riding (even though iOS wakes up the app in the background at this point to deliver the Bluetooth events from the bike). The user has to open the app manually at least once. On the other hand, this limitation may not be an issue for most use cases and will probably cut down on spamming/abuse significantly. The app must keep running in the background to update the activity (or use push notifications) As long as the app keeps running (in the foreground or background), it can update the Live Activity as often as it wants (I think). This is ideal for the bike computer as the app keeps running in the background processing Bluetooth events while the bike is in motion. I assume the same applies to other apps that can remain alive in the background, such as audio players or navigation apps doing continuous location monitoring. Updating the Live Activity once per second was no problem in my testing, and I didn’t experience any rate limiting. Most apps get suspended in the background, however. They must use push notifications to update their Live Activity (or background tasks or some other mechanism to have the system wake you up). Apple introduced a new kind of push notification that is delivered directly to the Live Activity, bypassing the app altogether. I haven’t played with push notification updates, so I don’t know the benefits of using this method over sending a silent push notification to wake the app and updating the Live Activity from there. Probably less aggressive rate limiting? Lock screen color matching I haven’t found a good way to match my Live Activity’s colors to the current system colors on the lock screen. By default, text in a Live Activity is black in light mode, whereas the built-in lock screen themes seem to favor white or other light text colors. If there is an API or environment value that allows apps to match the color style of the current lock screen, I haven’t found it. I experimented with various foreground styles, such as materials, without success. I ended up hardcoding the foreground color, but I’m not satisfied with the result. Depending on the user’s lock screen theme, the Live Activity can look out of place. The default text color of a Live Activity in light mode is black. This doesn’t match most lock screen themes. Animations can’t be disabled Apple’s guide clearly states that developers have little control over animations in a Live Activity: Animate content updates When you define the user interface of your Live Activity, the system ignores any animation modifiers — for example, withAnimation(_:_:) and animation(_:value:) — and uses the system’s animation timing instead. However, the system performs some animation when the dynamic content of the Live Activity changes. Text views animate content changes with blurred content transitions, and the system animates content transitions for images and SF Symbols. If you add or remove views from the user interface based on content or state changes, views fade in and out. Use the following view transitions to configure these built-in transitions: opacity, move(edge:), slide, push(from:), or combinations of them. Additionally, request animations for timer text with numericText(countsDown:). It makes total sense to me that Apple doesn’t want developers to go crazy with animations on the lock screen, and perhaps having full control over animations also makes it easier for Apple to integrate Live Activities into the always-on display that’s probably coming on the next iPhone. What surprised me is that I couldn’t find a way to disable the text change animations altogether. I find the blurred text transitions for the large speed value quite distracting and I think this label would look better without any animations. But no combination of .animation(nil), .contentTransition(.identity), and .transition(.identity) would do this. Sharing code between app and widget A Live Activity is very much like a widget: the UI must live in your app’s widget extension. You start the Live Activity with code that runs in your app, though. Both targets (the app and the widget extension) need access to a common data type that represents the data the widget displays. You should have a third target (a framework or SwiftPM package) that contains such shared types and APIs and that the downstream targets import. Availability annotations Update September 22, 2022: This limitation no longer applies. The iOS 16.1 SDK added the ability to have availability conditions in WidgetBundle. Source: Tweet from Luca Bernardi (2022-09-20). WidgetBundle apparently doesn’t support widgets with different minimum deployment targets. If your widget extension has a deployment target of iOS 14 or 15 for an existing widget and you now want to add a Live Activity, I’d expect your widget bundle to look like this: @main struct MyWidgets: WidgetBundle { var body: some Widget { MyNormalWidget() // Error: Closure containing control flow statement cannot // be used with result builder 'WidgetBundleBuilder' if #available(iOSApplicationExtension 16.0, *) { MyLiveActivityWidget() } } } But this doesn’t compile because the result builder type used by WidgetBundle doesn’t support availability conditions. I hope Apple fixes this. This wasn’t a problem for me because our app didn’t have any widgets until now, so I just set the deployment target of the widget extension to iOS 16.0. If you have existing widgets and can’t require iOS 16 yet, a workaround is to add a second widget extension target just for the Live Activity. I haven’t tried this, but WidgetKit explicitly supports having multiple widget extensions, so it should work: Typically, you include all your widgets in a single widget extension, although your app can contain multiple extensions.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      How @MainActor works

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        @MainActor is a Swift annotation to coerce a function to always run on the main thread and to enable the compiler to verify this. How does this work? In this article, I’m going to reimplement @MainActor in a slightly simplified form for illustration purposes, mainly to show how little “magic” there is to it. The code of the real implementation in the Swift standard library is available in the Swift repository. @MainActor relies on two Swift features, one of them unofficial: global actors and custom executors. Global actors MainActor is a global actor. That is, it provides a single actor instance that is shared between all places in the code that are annotated with @MainActor. All global actors must implement the shared property that’s defined in the GlobalActor protocol (every global actor implicitly conforms to this protocol): @globalActor final actor MyMainActor { // Requirements from the implicit GlobalActor conformance typealias ActorType = MyMainActor static var shared: ActorType = MyMainActor() // Don’t allow others to create instances private init() {} } At this point, we have a global actor that has the same semantics as any other actor. That is, functions annotated with @MyMainActor will run on a thread in the cooperative thread pool managed by the Swift runtime. To move the work to the main thread, we need another concept, custom executors. Executors A bit of terminology: The compiler splits async code into jobs. A job roughly corresponds to the code from one await (= potential suspension point) to the next. The runtime submits each job to an executor. The executor is the object that decides in which order and in which context (i.e. which thread or dispatch queue) to run the jobs. Swift ships with two built-in executors: the default concurrent executor, used for “normal”, non-actor-isolated async functions, and a default serial executor. Every actor instance has its own instance of this default serial executor and runs its code on it. Since the serial executor, like a serial dispatch queue, only runs a single job at a time, this prevents concurrent accesses to the actor’s state. Custom executors As of Swift 5.6, executors are an implementation detail of Swift’s concurrency system, but it’s almost certain that they will become an official feature fairly soon. Why? Because it can sometimes be useful to have more control over the execution context of async code. Some examples are listed in a draft proposal for allowing developers to implement custom executors that was first pitched in February 2021 but then didn’t make the cut for Swift 5.5. @MainActor already uses the unofficial ability for an actor to provide a custom executor, and we’re going to do the same for our reimplementation. A serial executor that runs its job on the main dispatch queue is implemented as follows. The interesting bit is the enqueue method, where we tell the job to run on the main dispatch queue: final class MainExecutor: SerialExecutor { func asUnownedSerialExecutor() -> UnownedSerialExecutor { UnownedSerialExecutor(ordinary: self) } func enqueue(_ job: UnownedJob) { DispatchQueue.main.async { job._runSynchronously(on: self.asUnownedSerialExecutor()) } } } We’re responsible for keeping an instance of the executor alive, so let’s store it in a global: private let mainExecutor = MainExecutor() Finally, we need to tell our global actor to use the new executor: import Dispatch @globalActor final actor MyMainActor { // ... // Requirement from the implicit GlobalActor conformance static var sharedUnownedExecutor: UnownedSerialExecutor { mainExecutor.asUnownedSerialExecutor() } // Requirement from the implicit Actor conformance nonisolated var unownedExecutor: UnownedSerialExecutor { mainExecutor.asUnownedSerialExecutor() } } That’s all there is to reimplement the basics of @MainActor. Conclusion The full code is on GitHub, including a usage example to demonstrate that the @MyMainActor annotations work. John McCall’s draft proposal for custom executors is worth reading, particularly the philosophy section. It’s an easy-to-read summary of some of the design principles behind Swift’s concurrency system: Swift’s concurrency design sees system threads as expensive and rather precious resources. … It is therefore best if the system allocates a small number of threads — just enough to saturate the available cores — and for those threads [to] only block for extended periods when there is no pending work in the program. Individual functions cannot effectively make this decision about blocking, because they lack a holistic understanding of the state of the program. Instead, the decision must be made by a centralized system which manages most of the execution resources in the program. This basic philosophy of how best to use system threads drives some of the most basic aspects of Swift’s concurrency design. In particular, the main reason to add async functions is to make it far easier to write functions that, unlike standard functions, will reliably abandon a thread when they need to wait for something to complete. And: The default concurrent executor is used to run jobs that don’t need to run somewhere more specific. It is based on a fixed-width thread pool that scales to the number of available cores. Programmers therefore do not need to worry that creating too many jobs at once will cause a thread explosion that will starve the program of resources.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        AttributedString’s Codable format and what it has to do with Unicode

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          Here’s a simple AttributedString with some formatting: import Foundation let str = try! AttributedString( markdown: "Café **Sol**", options: .init(interpretedSyntax: .inlineOnly) ) AttributedString is Codable. If your task was to design the encoding format for an attributed string, what would you come up with? Something like this seems reasonable (in JSON with comments): { "text": "Café Sol", "runs": [ { // start..<end in Character offsets "range": [5, 8], "attrs": { "strong": true } } ] } This stores the text alongside an array of runs of formatting attributes. Each run consists of a character range and an attribute dictionary. Unicode is complicated But this format is bad and can break in various ways. The problem is that the character offsets that define the runs aren’t guaranteed to be stable. The definition of what constitutes a Character, i.e. a user-perceived character, or a Unicode grapheme cluster, can and does change in new Unicode versions. If we decoded an attributed string that had been serialized on a different OS version (before Swift 5.6, Swift used the OS’s Unicode library for determining character boundaries), or by code compiled with a different Swift version (since Swift 5.6, Swift uses its own grapheme breaking algorithm that will be updated alongside the Unicode standard)1, the character ranges might no longer represent the original intent, or even become invalid. Update April 11, 2024: See this Swift forum post I wrote for an example where the Unicode rules for grapheme cluster segmentation changed for flag emoji. This change caused a corresponding change in how Swift counts the Characters in a string containing consecutive flags, such as "🇦🇷🇯🇵". Normalization forms So let’s use UTF-8 byte offsets for the ranges, I hear you say. This avoids the first issue but still isn’t safe, because some characters, such as the é in the example string, have more than one representation in Unicode: it can be either the standalone character é (Latin small letter e with acute) or the combination of e + ◌́ (Combining acute accent). The Unicode standard calls these variants normalization forms.2 The first form needs 2 bytes in UTF-8, whereas the second uses 3 bytes, so subsequent ranges would be off by one if the string and the ranges used different normalization forms. Now in theory, the string itself and the ranges should use the same normalization form upon serialization, avoiding the problem. But this is almost impossible to guarantee if the serialized data passes through other systems that may (inadvertently or not) change the Unicode normalization of the strings that pass through them. A safer option would be to store the text not as a string but as a blob of UTF-8 bytes, because serialization/networking/storage layers generally don’t mess with binary data. But even then you’d have to be careful in the encoding and decoding code to apply the formatting attributes before any normalization takes place. Depending on how your programming language handles Unicode, this may not be so easy. Foundation’s solution The people on the Foundation team know all this, of course, and chose a better encoding format for Attributed String. Let’s take a look.3 let encoder = JSONEncoder() encoder.outputFormatting = [.prettyPrinted, .sortedKeys] let jsonData = try encoder.encode(str) let json = String(decoding: jsonData, as: UTF8.self) This is how our sample string is encoded: [ "Café ", { }, "Sol", { "NSInlinePresentationIntent" : 2 } ] This is an array of runs, where each run consists of a text segment and a dictionary of formatting attributes. The important point is that the formatting attributes are directly associated with the text segments they belong to, not indirectly via brittle byte or character offsets. (This encoding format is also more space-efficient and possibly better represents the in-memory layout of AttributedString, but that’s beside the point for this discussion.) There’s still a (smaller) potential problem here if the character boundary rules change for code points that span two adjacent text segments: the last character of run N and the first character of run N+1 might suddenly form a single character (grapheme cluster) in a new Unicode version. In that case, the decoding code will have to decide which formatting attributes to apply to this new character. But this is a much smaller issue because it only affects the characters in question. Unlike our original example, where an off-by-one error in run N would affect all subsequent runs, all other runs are untouched. Related forum discussion: Itai Ferber on why Character isn’t Codable. Storing string offsets is a bad idea We can extract a general lesson out of this: Don’t store string indices or offsets if possible. They aren’t stable over time or across runtime environments. On Apple platforms, the Swift standard library ships as part of the OS so I’d guess that the standard library’s grapheme breaking algorithm will be based on the same Unicode version that ships with the corresponding OS version. This is effectively no change in behavior compared to the pre-Swift 5.6 world (where the OS’s ICU library determined the Unicode version). On non-ABI-stable platforms (e.g. Linux and Windows), the Unicode version used by your program is determined by the version of the Swift compiler your program is compiled with, if my understanding is correct. ↩︎ The Swift standard library doesn’t have APIs for Unicode normalization yet, but you can use the corresponding NSString APIs, which are automatically added to String when you import Foundation: import Foundation let precomposed = "é".precomposedStringWithCanonicalMapping let decomposed = "é".decomposedStringWithCanonicalMapping precomposed == decomposed // → true precomposed.unicodeScalars.count // → 1 decomposed.unicodeScalars.count // → 2 precomposed.utf8.count // → 2 decomposed.utf8.count // → 3 ↩︎ By the way, I see a lot of code using String(jsonData, encoding: .utf8)! to create a string from UTF-8 data. String(decoding: jsonData, as: UTF8.self) saves you a force-unwrap and is arguably “cleaner” because it doesn’t depend on Foundation. Since it never fails, it’ll insert replacement characters into the string if it encounters invalid byte sequences. ↩︎

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          A heterogeneous dictionary with strong types in Swift

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            The environment in SwiftUI is sort of like a global dictionary but with stronger types: each key (represented by a key path) can have its own specific value type. For example, the \.isEnabled key stores a boolean value, whereas the \.font key stores an Optional<Font>. I wrote a custom dictionary type that can do the same thing. The HeterogeneousDictionary struct I show in this article stores mixed key-value pairs where each key defines the type of value it stores. The public API is fully type-safe, no casting required. Usage I’ll start with an example of the finished API. Here’s a dictionary for storing text formatting attributes: import AppKit var dict = HeterogeneousDictionary<TextAttributes>() dict[ForegroundColor.self] // → nil // The value type of this key is NSColor dict[ForegroundColor.self] = NSColor.systemRed dict[ForegroundColor.self] // → NSColor.systemRed dict[FontSize.self] // → nil // The value type of this key is Double dict[FontSize.self] = 24 dict[FontSize.self] // → 24 (type: Optional<Double>) We also need some boilerplate to define the set of keys and their associated value types. The code to do this for three keys (font, font size, foreground color) looks like this: // The domain (aka "keyspace") enum TextAttributes {} struct FontSize: HeterogeneousDictionaryKey { typealias Domain = TextAttributes typealias Value = Double } struct Font: HeterogeneousDictionaryKey { typealias Domain = TextAttributes typealias Value = NSFont } struct ForegroundColor: HeterogeneousDictionaryKey { typealias Domain = TextAttributes typealias Value = NSColor } Yes, this is fairly long, which is one of the downsides of this approach. At least you only have to write it once per “keyspace”. I’ll walk you through it step by step. Notes on the API Using types as keys As you can see in this line, the dictionary keys are types (more precisely, metatype values): dict[FontSize.self] = 24 This is another parallel with the SwiftUI environment, which also uses types as keys (the public environment API uses key paths as keys, but you’ll see the types underneath if you ever define your own environment key). Why use types as keys? We want to establish a relationship between a key and the type of values it stores, and we want to make this connection known to the type system. The way to do this is by defining a type that sets up this link. Domains aka “keyspaces” A standard Dictionary is generic over its key and value types. This doesn’t work for our heterogeneous dictionary because we have multiple value types (and we want more type safety than Any provides). Instead, a HeterogeneousDictionary is parameterized with a domain: // The domain (aka "keyspace") enum TextAttributes {} var dict = HeterogeneousDictionary<TextAttributes>() The domain is the “keyspace” that defines the set of legal keys for this dictionary. Only keys that belong to the domain can be put into the dictionary. The domain type has no protocol constraints; you can use any type for this. Defining keys A key is a type that conforms to the HeterogeneousDictionaryKey protocol. The protocol has two associated types that define the relationships between the key and its domain and value type: protocol HeterogeneousDictionaryKey { /// The "namespace" the key belongs to. associatedtype Domain /// The type of values that can be stored /// under this key in the dictionary. associatedtype Value } You define a key by creating a type and adding the conformance: struct Font: HeterogeneousDictionaryKey { typealias Domain = TextAttributes typealias Value = NSFont } Implementation notes A minimal implementation of the dictionary type is quite short: struct HeterogeneousDictionary<Domain> { private var storage: [ObjectIdentifier: Any] = [:] var count: Int { self.storage.count } subscript<Key>(key: Key.Type) -> Key.Value? where Key: HeterogeneousDictionaryKey, Key.Domain == Domain { get { self.storage[ObjectIdentifier(key)] as! Key.Value? } set { self.storage[ObjectIdentifier(key)] = newValue } } } Internal storage private var storage: [ObjectIdentifier: Any] = [:] Internally, HeterogeneousDictionary uses a dictionary of type [ObjectIdentifier: Any] for storage. We can’t use a metatype such as Font.self directly as a dictionary key because metatypes aren’t hashable. But we can use the metatype’s ObjectIdentifier, which is essentially the address of the type’s representation in memory. Subscript subscript<Key>(key: Key.Type) -> Key.Value? where Key: HeterogeneousDictionaryKey, Key.Domain == Domain { get { self.storage[ObjectIdentifier(key)] as! Key.Value? } set { self.storage[ObjectIdentifier(key)] = newValue } } The subscript implementation constrains its arguments to keys in the same domain as the dictionary’s domain. This ensures that you can’t subscript a dictionary for text attributes with some other unrelated key. If you find this too restrictive, you could also remove all references to the Domain type from the code; it would still work. Using key paths as keys Types as keys don’t have the best syntax. I think you’ll agree that dict[FontSize.self] doesn’t read as nice as dict[\.fontSize], so I looked into providing a convenience API based on key paths. My preferred solution would be if users could define static helper properties on the domain type, which the dictionary subscript would then accept as key paths, like so: extension TextAttributes { static var fontSize: FontSize.Type { FontSize.self } // Same for font and foregroundColor } Sadly, this doesn’t work because Swift 5.6 doesn’t (yet?) support key paths to static properties (relevant forum thread). We have to introduce a separate helper type that acts as a namespace for these helper properties. Since the dictionary type can create an instance of the helper type, it can access the non-static helper properties. This doesn’t feel as clean to me, but it works. I called the helper type HeterogeneousDictionaryValues as a parallel with EnvironmentValues, which serves the same purpose in SwiftUI. The code for this is included in the Gist. Drawbacks Is the HeterogeneousDictionary type useful? I’m not sure. I wrote this mostly as an exercise and haven’t used it yet in a real project. In most cases, if you need a heterogeneous record with full type safety, it’s probably easier to just write a new struct where each property is optional — the boilerplate for defining the dictionary keys is certainly longer and harder to read. For representing partial values, i.e. struct-like records where some but not all properties have values, take a look at these two approaches from 2018: Ian Keen, Type-safe temporary models (2018-06-05) Joseph Duffy, Partial in Swift (2018-07-10), also available as a library These use a similar storage approach (a dictionary of Any values with custom accessors to make it type-safe), but they use an existing struct as the domain/keyspace, combined with partial key paths into that struct as the keys. I honestly think that this is the better design for most situations. Aside from the boilerplate, here are a few more weaknesses of HeterogeneousDictionary: Storage is inefficient because values are boxed in Any containers Accessing values is inefficient: every access requires unboxing HeterogeneousDictionary can’t easily conform to Sequence and Collection because these protocols require a uniform element type The code The full code is available in a Gist.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            Advanced Swift, fifth edition

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              We released the fifth edition of our book Advanced Swift a few days ago. You can buy the ebook on the objc.io site. The hardcover print edition is printed and sold by Amazon (amazon.com, amazon.co.uk, amazon.de). Highlights of the new edition: Fully updated for Swift 5.6 A new Concurrency chapter covering async/await, structured concurrency, and actors New content on property wrappers, result builders, protocols, and generics The print edition is now a hardcover (for the same price) Free update for owners of the ebook A growing book for a growing language Updating the book always turns out to be more work than I expect. Swift has grown substantially since our last release (for Swift 5.0), and the size of the book reflects this. The fifth edition is 76 % longer than the first edition from 2016. This time, we barely stayed under 1 million characters: Character counts of Advanced Swift editions from 2016–2022. Many thanks to our editor, Natalye, for reading all this and improving our Dutch/German dialect of English. Hardcover For the first time, the print edition comes in hardcover (for the same price). Being able to offer this makes me very happy. The hardcover book looks much better and is more likely to stay open when laid flat on a table. We also increased the page size from 15×23 cm (6×9 in) to 18×25 cm (7×10 in) to keep the page count manageable (Amazon’s print on demand service limits hardcover books to 550 pages). I hope you enjoy the new edition. If you decide to buy the book or if you bought it in the past, thank you very much! And if you’re willing to write a review on Amazon, we’d appreciate it.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              Synchronous functions can support cancellation too

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                Cancellation is a Swift concurrency feature, but this doesn’t mean it’s only available in async functions. Synchronous functions can also support cancellation, and by doing so they’ll become better concurrency citizens when called from async code. Motivating example: JSONDecoder Supporting cancellation makes sense for functions that can block for significant amounts of time (say, more than a few milliseconds). Take JSON decoding as an example. Suppose we wrote an async function that performs a network request and decodes the downloaded JSON data: import Foundation func loadJSON<T: Decodable>(_ type: T.Type, from url: URL) async throws -> T { let (data, _) = try await URLSession.shared.data(from: url) return try JSONDecoder().decode(type, from: data) } The JSONDecoder.decode call is synchronous: it will block its thread until it completes. And if the download is large, decoding may take hundreds of milliseconds or even longer. Avoid blocking if possible In general, async code should avoid calling blocking APIs if possible. Instead, async functions are expected to suspend regularly to give waiting tasks a chance to run. But JSONDecoder doesn’t have an async API (yet?), and I’m not even sure it can provide one that works with the existing Codable protocols, so let’s work with what we have. And if you think about it, it’s not totally unreasonable for JSONDecoder to block. After all, it is performing CPU-intensive work (assuming the data it’s working on doesn’t have to be paged in), and this work has to happen on some thread. Async/await works best for I/O-bound functions that spend most of their time waiting for the disk or the network. If an I/O-bound function suspends, the runtime can give the function’s thread to another task that can make more productive use of the CPU. Responding to cancellation Cancellation is a cooperative process. Canceling a task only sets a flag in the task’s metadata. It’s up to individual functions to periodically check for cancellation and abort if necessary. If a function doesn’t respond promptly to cancellation or outright ignores the cancellation flag, the program may appear to the user to be stalling. Now, if the task is canceled while JSONDecoder.decode is running, our loadJSON function can’t react properly because it can’t interrupt the decoding process. To fix this, the decode method would have to perform its own periodic cancellation checks, using the usual APIs, Task.isCancelled or Task.checkCancellation(). These can be called from anywhere, including synchronous code. Internals How does this work? How can synchronous code access task-specific metadata? Here’s the code for Task.isCancelled in the standard library: extension Task where Success == Never, Failure == Never { public static var isCancelled: Bool { withUnsafeCurrentTask { task in task?.isCancelled ?? false } } } This calls withUnsafeCurrentTask to get a handle to the current task. When the runtime schedules a task to run on a particular thread, it stores a pointer to the task object in that thread’s thread-local storage, where any code running on that thread – sync or async – can access it. If task == nil, there is no current task, i.e. we haven’t been called (directly or indirectly) from an async function. In this case, cancellation doesn’t apply, so we can return false. If we do have a task handle, we ask the task for its isCancelled flag and return that. Reading the flag is an atomic (thread-safe) operation because other threads may be writing to it concurrently. Conclusion I hope we’ll see cancellation support in the Foundation encoders and decoders in the future. If you have written synchronous functions that can potentially block their thread for a significant amount of time, consider adding periodic cancellation checks. It’s a quick way to make your code work better with the concurrency system, and you don’t even have to change your API to do it. Update February 2, 2022: Jordan Rose argues that cancellation support for synchronous functions should be opt-in because it introduces a failure mode that’s hard to reason about locally as the “source“ of the failure (the async context) may be several levels removed from the call site. Definitely something to consider!

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                Cancellation can come in many forms

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  In Swift’s concurrency model, cancellation is cooperative. To be a good concurrency citizen, code must periodically check if the current task has been cancelled, and react accordingly. You can check for cancellation by calling Task.isCancelled or with try Task.checkCancellation() — the latter will exit by throwing a CancellationError if the task has been cancelled. By convention, functions should react to cancellation by throwing a CancellationError. But this convention isn’t enforced, so callers must be aware that cancellation can manifest itself in other forms. Here are some other ways how functions might respond to cancellation: Throw a different error. For example, the async networking APIs in Foundation, such as URLSession.data(from: URL), throw a URLError with the code URLError.Code.cancelled on cancellation. It’d be nice if URLSession translated this error to CancellationError, but it doesn’t. Return a partial result. A function that has completed part of its work when cancellation occurs may choose to return a partial result rather than throwing the work away and aborting. In fact, this may be the best choice for a non-throwing function. But note that this behavior can be extremely surprising to callers, so be sure to document it clearly. Do nothing. Functions are supposed to react promptly to cancellation, but callers must assume the worst. Even if cancelled, a function might run to completion and finish normally. Or it might eventually respond to cancellation by aborting, but not promptly because it doesn’t perform its cancellation checks often enough. So as the caller of a function, you can’t really rely on specific cancellation behavior unless you know how the callee is implemented. Code that wants to know if its task has been cancelled should itself call Task.isCancelled, rather than counting on catching a CancellationError from a callee.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  Software Development News

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  March 2025: All AI updates from the past month

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  • Latest News
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  • AI

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  Software companies are constantly trying to add more and more AI features to their platforms, and AI companies are constantly releasing new models and features.  Here are all the major AI updates we covered in the month of March. Google releases reasoning model Gemini 2.5, its “most intelligent AI model” yet Gemini 2.0 Flash Thinking … continue reading

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  The post March 2025: All AI updates from the past month appeared first on SD Times.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  Software companies are constantly trying to add more and more AI features to their platforms, and AI companies are constantly releasing new models and features. Here are all the major AI updates we covered in the month of March. Google releases reasoning model Gemini 2.5, its “most intelligent AI model” yet Gemini 2.0 Flash Thinking was the company’s first reasoning model, and Gemini 2.5 builds on that with a better base model and improved post-training. In its announcement, Google revealed that all of its future AI models will have reasoning capabilities built in. The first Gemini 2.5 model is Gemini 2.5 Pro Experimental, and it leads in LMArena benchmarks over other reasoning models like OpenAI o3-mini, Claude 3.5 Sonnet, and DeepSeek R1. “Gemini 2.5 models are thinking models, capable of reasoning through their thoughts before responding, resulting in enhanced performance and improved accuracy. In the field of AI, a system’s capacity for “reasoning” refers to more than just classification and prediction. It refers to its ability to analyze information, draw logical conclusions, incorporate context and nuance, and make informed decisions,” Koray Kavukcuoglu, CTO of Google DeepMind, wrote in a blog post. OpenAI announces 4o Image Generation The latest image generation model improves on text rendering, has the ability to refine images through multiple follow-up prompts, and offers better instruction following, with the ability to handle up to 10-20 different objects in a prompt. It can also perform in-context learning to analyze and learn from user-uploaded images, and the model also links its knowledge between text and images to generate better results. 4o image generation has begun rolling out for Plus, Pro, Team, and Free users as the default image generator, and access will soon be available for Enterprise and Edu users. Microsoft unveils new reasoning agents in Microsoft 365 Copilot The two agents, Researcher and Analyst, can help users analyze vast amounts of information, spanning emails, meetings, files, chats, and more. Researcher is ideal for multi-step research, such as building a go-to-market strategy based on both the context of a company’s work and broader competitive data found online. Beyond data in Microsoft 365, it can also leverage third-party connectors to bring in data from sources like Salesforce, ServiceNow, and Confluence. Analyst is designed for complex data analysis, such as turning raw data from multiple spreadsheets into a demand forecast for a new product or a visualization of customer purchasing patterns. These two agents will begin rolling out to Microsoft 365 Copilot subscribers starting in April as part of the Frontier early access program. Microsoft Security Copilot gets several new agents The new agents include a Phishing Triage Agent in Microsoft Defender, Alert Triage Agents in Microsoft Purview, Conditional Access Optimization Agent in Microsoft Entra, Vulnerability Remediation Agent in Microsoft Intune, and Threat Intelligence Briefing Agent in Security Copilot. The company also announced five additional agents from its Microsoft Security partners: Privacy Breach Response Agent by OneTrust, Network Supervisor Agent by Aviatrix, SecOps Tooling Agent by BlueVoyant, Alert Triage Agent by Tanium, and Task Optimizer Agent by Fletch. The agents will be available in preview starting in April. “Building on the transformative capabilities of Security Copilot, the six Microsoft Security Copilot agents enable teams to autonomously handle high-volume security and IT tasks while seamlessly integrating with Microsoft Security solutions. Purpose-built for security, agents learn from feedback, adapt to workflows, and operate securely—aligned to Microsoft’s Zero Trust framework. With security teams fully in control, agents accelerate responses, prioritize risks, and drive efficiency to enable proactive protection and strengthen an organization’s security posture,” Vasu Jakkal, corporate vice president of Microsoft Security, wrote in a blog post. Red Hat AI offers new capabilities across Red Hat OpenShift AI Red Hat OpenShift AI 2.18 adds new features such as distributed serving that allows IT teams to split model serving across multiple GPUs, an end-to-end model tuning experience across InstructLab and Red Hat OpenShift AI data science pipelines, and model evaluation. This release also includes a preview of AI Guardrails, which offer additional methods for identifying and mitigating “potentially hateful, abusive or profane speech, personally identifiable information, competitive information or other data limited by corporate policies.” Akamai launches new platform for AI inference at the edge Akamai has announced the launch of Akamai Cloud Inference, a new solution that provides tools for developers to build and run AI applications at the edge. According to Akamai, bringing data workloads closer to end users with this tool can result in 3x better throughput and reduce latency up to 2.5x. Akamai Cloud Inference offers a variety of compute types, from classic CPUs to GPUs to tailored ASIC VPUs. It offers integrations with Nvidia’s AI ecosystem, leveraging technologies such as Triton, TAO Toolkit, TensorRT, and NVFlare. Due to a partnership with VAST Data, the solution provides access to real-time data so that developers can accelerate inference-related tasks. The solution also offers highly scalable object storage and integration with vector database vendors like Aiven and Milvus. AlexNet source code is now open source AlexNet is a neural network for recognizing images that was created in 2012 by University of Toronto graduate students Alex Krizhevsky and Ilya Sutskever and their advisor Geoffrey Hinton. “Before AlexNet, almost none of the leading computer vision papers used neural nets. After it, almost all of them would. AlexNet was just the beginning. In the next decade, neural networks would advance to synthesize believable human voices, beat champion Go players, model human language, and generate artwork, culminating with the release of ChatGPT in 2022 by OpenAI, a company cofounded by Sutskever,” wrote Hansem Hsu, curator of the Computer History Museum Software History Center, the organization that is releasing the source code, in partnership with Google. The source code can be found here. Anthropic’s Claude can now search the web when generating responses Anthropic has announced that Claude can now search the Internet, allowing it to generate more up-to-date and relevant responses. For instance, a developer who is getting an error updating a dependency in TypeScript 5.5 could ask Claude if there were any breaking changes between version 5.4 and 5.5 and also ask for recommended fixes. Claude will respond with direct citations of its web sources, allowing users to fact check the information. Google launches Canvas to enable easier collaboration with Gemini Google is making it easier for developers to collaborate with Gemini with the launch of Canvas, an interactive space to create and refine code. Canvas could be used to build reports, blog posts, study guides, visual timelines, interactive prototypes, code snippets, and more. The new tool makes it easier for users to refine their work, such as highlighting a paragraph and asking Gemini to make it more concise or professional. OpenAI adds new audio models to API The new speech-to-text and text-to-speech models will enable developers to “build more powerful, customizable, and intelligent voice agents that offer real value,” according to OpenAI. The updated speech-to-text models perform particularly well in scenarios involving accents, noisy environments, and fluctuating speech speeds, improving transcription quality. This makes them particularly well-suited for use cases such as call centers and meeting note transcription, OpenAI explained. Developers will now be able to prompt the text-to-speech model to speak in a certain way, such as “talk like a sympathetic customer service agent.” Nvidia unveils several AI advancements at GTC During its GTC conference this week Nvidia made a number of announcements related to AI, including AI-Q Blueprint, which is a system for building agentic systems. It provides references for integrating Nvidia accelerated computing, partner storage platforms, and software and tools. The company also announced a family of open reasoning AI models, Llama Nemotron, which are based on Meta’s Llama models and offer improvements over the base model in multistep math, coding, reasoning, and complex decision making. A full list of announcements from GTC can be found here. IBM Research announces Agent Communication Protocol Agent Communication Protocol (ACP) is a standard for agent communication to enable interoperability, simplified development, and the ability to reuse solutions. ACP is an extension of Model Communication Protocol (MCP), which is a standard introduced by Anthropic to standardize how apps and LLMs communicate. “Current agent systems often use diverse communication standards, causing complexity, integration difficulties, and vendor lock-in. ACP addresses these issues uniquely by standardizing interactions tailored specifically for agents that handle natural language inputs and depend on externally hosted models. By accommodating these agent-specific needs, ACP simplifies integration and promotes effective collaboration across agent-based ecosystems,” the draft proposal states. Oracle launches AI Agent Studio AI Agent Studio is a platform for creating, extending, deploying, and managing AI agents and agent teams. It is part of Oracle Fusion Cloud Applications Suite, and includes over 50 pre-packaged agents. It offers capabilities like agent template libraries, agent team orchestration, extensibility of the prepackaged agents, flexibility in LLM choice, third-party system integration, a trust and security framework, and validation and testing tools. “AI agents are the next phase of evolution in enterprise applications and just like with existing applications, business leaders need the flexibility to create specific functionality to address their unique and evolving business needs,” said Steve Miranda, executive vice president of applications at Oracle. “Our AI Agent Studio builds on the 50+ AI agents we have already introduced and gives our customers and partners the flexibility to easily create and manage their own AI agents. With the agents already embedded in Fusion Applications and our new AI Agent Studio, customers will be able to further extend automation and ultimately, achieve more while spending less.” WSO2 updates AI-powered IDP Choreo The latest release adds new capabilities such as: Customizable CI pipelines and parallel deployment options AI-driven cost insights, including recommendations for how to optimize costs Automatic alerts from metrics and logs Support for local pipelines and observability Choreo’s AI copilot has also been updated with support for encryption keys for APIs, hotfix deployment pipelines, and support for environment-aware configuration groups and unified configuration declaration. And finally, WSO2 is also releasing an open source version of Choreo. “AI holds an opportunity for enterprises seeking to compete with new intelligent digital experiences, but the complexity of today’s infrastructure is hindering their efforts,” said Kanchana Wickremasinghe, WSO2 vice president and general manager of Choreo at WSO2. “The latest release of our Choreo AI-native IDP, available in the cloud and as open-source software, is clearing the way for enterprises to innovate by extending AI capabilities that help software engineers deliver new apps faster while enabling platform engineers to quickly respond to developers’ ever-changing requirements and expectations.” Stravito enhances its generative AI assistant with new capabilities Stravito Assistant now has a Focus Mode where it will go into a deep analysis mode when given a set of reports, videos, or collections to detect patterns and insights from those collections of data. Another new feature—Snapshots—provides instant summaries of a report, so that users can get the key takeaways from a document quickly. And additionally, Stravito Assistant now supports over 100 languages. “These updates reinforce our commitment to providing purpose-built AI-powered tools that help global enterprises leverage their market research to make data-driven, cost-effective decisions that fuel innovation and long-term growth,” said Thor Olof Philogène, founder and CEO of Stravito. Google announces Gemma 3 Gemma 3 is Google’s latest AI model, offering improved math, reasoning, and chat capabilities. It can handle context windows of up to 128k tokens, understand 140 languages, and comes in four sizes: 1B, 4B, 12B, and 27B. It is a multimodal model, and it supports images and videos as inputs, which allows it to analyze images, answer questions about a picture, compare images, identify objects, or reply about text on an image. Gemma 3 is available as either a pre-trained model that can be fine-tuned for specific use cases, or as a general-purpose instruction-tuned model. It is available in Google AI Studio, or can be downloaded through Hugging Face or Kaggle. OpenAI reveals Responses API, Agents SDK for building agentic experiences OpenAI is releasing new tools and APIs to help developers build agentic experiences. The Responses API allows developers to more easily integrate OpenAI’s tools into their own applications. “As model capabilities continue to evolve, we believe the Responses API will provide a more flexible foundation for developers building agentic applications. With a single Responses API call, developers will be able to solve increasingly complex tasks using multiple tools and model turns,” OpenAI wrote. The Responses API comes with several built-in tools, including: Web search, which allows for retrieval of information from the Internet File search, which allows for retrieval of information from large volumes of documents Computer use, which captures mouse and keyboard actions generated by a model so that developers can automate computer tasks. OpenAI also announced the Agents SDK, an open source tool for orchestrating multi-agent workflows. According to OpenAI, the Agents SDK can be used for a variety of scenarios, including customer support automation, multi-step research, content generation, code review, and sales prospecting. Boomi launches AI Studio Boomi AI Studio is a platform for designing, governing, and orchestrating AI agents at scale. It consists of multiple components, including: Agent Designer, which provides no-code templates for building and deploying agents Agent Control Tower, which provides monitoring of agents Agent Garden, which allows developers to interact with agents in natural language Agent Marketplace, where developers can find and download AI agents from Boomi and its partners. “With Boomi AI Studio, we’re giving organizations a powerful yet accessible way to build, monitor, and orchestrate AI agents with trust, security, and governance at the core,” said Ed Macosky, chief product and technology officer at Boomi. “As of today, Boomi has deployed more than 25,000 AI Agents for customers. This strong market adoption of our AI agents highlights not only the real value they’re delivering, but also the need for a solution that enables organizations to leverage AI responsibly while accelerating innovation and achieving transformative outcomes.” Amazon SageMaker Unified Studio is now generally available The platform allows developers to find and access all of the data in their organization and act on it using a variety of AWS tools, such as Amazon Athena, Amazon EMR, AWS Glue, Amazon Redshift, Amazon Managed Workflows for Apache Airflow (Amazon MWAA), and SageMaker Studio. It was first announced as a preview at AWS re:Invent last year, and new capabilities added since then include support in Amazon Bedrock for foundation models like Anthropic Claude 3.7 Sonnet and DeepSeek-R1, and integration with the generative AI assistant Amazon Q developer. Amazon SageMaker Unified Studio is available in US East (N. Virginia, Ohio), US West (Oregon), Asia Pacific (Seoul, Singapore, Sydney, Tokyo), Canada (Central), Europe (Frankfurt, Ireland, London), and South America (São Paulo) AWS regions. “SageMaker Unified Studio breaks down silos in data and tools, giving data engineers, data scientists, data analysts, ML developers and other data practitioners a single development experience. This saves development time and simplifies access control management so data practitioners can focus on what really matters to them—building data products and AI applications,” Donnie Prakoso, principal developer advocate at AWS, wrote in a blog post. Visual Studio now includes access to GPT-4o Copilot code completion model The code completion model was trained on over 275,000 public repositories in 30 different programming languages, on top of the GPT-4o training. This results in more accurate completion suggestions, Microsoft explained. It will be available for users working in Visual Studio 17.14 Preview 2, which was released this week. SUSE AI is updated with new features for agentic AI use cases SUSE AI is an open infrastructure platform for running AI workloads, and the latest release includes a number of new features, such as: Tools and blueprints for developing agentic workflows New observability features that provide insights into LLM token usage, GPU utilization, performance bottlenecks, and more LLM guardrails to ensure ethical AI practices, data privacy, and regulatory compliance SUSE AI Library now includes support for OpenWebUI Pipelines and PyTorch “Through close collaboration with our customers and partners since the launch of SUSE AI last year, we’ve gained additional and invaluable insights into the challenges of deploying production-ready AI workloads,” said Abhinav Puri, general manager of Portfolio Solutions & Services at SUSE. “This collaborative journey has allowed us to bolster our offerings and continue to provide customers strong transparency, trust, and openness in AI implementation. These new enhancements reflect our commitment to building on that partnership and delivering even greater value, while strengthening SUSE AI.” Eclipse Foundation releases Theia AI Theia AI is an open source framework for integrating LLMs into tools and IDEs. It gives developers full control and flexibility over how AI is implemented into their applications, from orchestrating the prompt engineering flow to defining agentic behavior to deciding which data sources are used. Additionally, the organization said that an AI-powered Theia IDE based on the Theia AI framework is now in alpha. The Eclipse Foundation says this IDE will give developers access to AI-enhanced development tools while also allowing them to maintain user control and transparency. Both tools are being contributed to the Eclipse Foundation by EclipseSource. “We believe that openness, flexibility, and transparency are key success factors for the innovative and sustainable adoption of AI in tools and IDEs,” said Jonas Helming, CEO of EclipseSource. “Large language models inherently introduce a significant level of indeterminism into modern workflows. Developers don’t need yet another proprietary black-box layer they cannot control and adapt. For tool builders developing reliable industrial solutions, it is even more crucial to have full customizability and control over every aspect of an AI-powered tool while also benefiting from a robust framework that allows them to focus on their domain-specific optimizations.” Anthropic makes changes to reduce token usage The company announced several new features to help users spend fewer tokens when interacting with its models: Cache-aware rate limits: Prompt cache read tokens don’t count against the Input Tokens Per Minute (ITPM) limit anymore on Claude 3.7 Sonnet, allowing users to optimize their prompt caching to get the most of their ITPM limit. Simpler prompt caching management: When a cache breakpoint is set, Claude will now automatically read from the longest previously cached prefix. This means that users won’t have to manually track and specify which cached segment to use, as Claude will automatically identify the most relevant one. Token-efficient tool use: Users can now specify that Claude calls tools in a token-efficient manner, resulting in up to a 70% reduction on output token consumption (the average reduction has been 14% among early adopters). Diffblue releases tool for verifying its AI-generated unit tests Diffblue Test Review was designed to give developers more confidence in accepting AI-generated unit tests. A recent Stack Overflow study found that only 2% of developers have confidence that AI-generated code is accurate. Test Review aims to give developers the insights needed to make an informed decision about accepting tests into their codebase. Developers can review each test and accept them all in one click, or send specific tests back or edit them before accepting them into the codebase. “We hope to win over developers who are apprehensive about integrating a fully-autonomous agent into their development workflow,” said Peter Schrammel, co-founder and CTO of Diffblue. “By lowering the barrier to adoption, developers can ease into an AI-powered iterative unit testing workflow, and ultimately, evolve into full autonomy and the remarkable scalability that results from it.” ScaleOut Software adds generative AI to Digital Twins service ScaleOut Digital Twins provides a framework for building and running digital twins at scale. Version 4 adds capabilities such as automatic anomaly detection using AI, the ability to use natural language prompts to create data visualizations, the ability to retrain machine learning algorithms in live systems, and other performance improvements. “ScaleOut Digital Twins Version 4 marks a pivotal step in harnessing AI and machine learning for real-time operational intelligence,” said Dr. William Bain, CEO and founder of ScaleOut Software. “By integrating these technologies, we’re transforming how organizations monitor and respond to complex system dynamics — making it faster and easier to uncover insights that would otherwise go unnoticed. This release is about more than just new features; it’s about redefining what’s possible in large-scale, real-time monitoring and predictive modeling.” JFrog launches end-to-end DevSecOps platform for deploying AI applications JFrog is releasing a new end-to-end solution for developing and deploying enterprise AI applications that brings together development teams, data scientists, and machine learning engineers into a single platform. JFrog ML provides a holistic view of the entire AI software supply chain, from software packages to LLMs, so that companies can ensure their AI applications are secured in the same way their traditional software is. It provides security scanning for AI models, whether they were created in-house or are from a third-party. Other key features include providing a single system of record, reproducible artifacts for all models created in the platform, simplified model development and deployment processes, and dataset management and feature store support. Anthropic Console now facilitates prompt collaboration Developers will now be able to share prompts with others through the Console. Team members have access to a shared library of prompts, eliminating the need to copy and paste prompts to share them. Additionally, Anthropic Console now supports the company’s latest model, Claude 3.7 Sonnet, and offers new capabilities to assist users in writing prompts for that model’s extended thinking mode, as well as setting the budget for extended thinking. Salesforce launches Agentforce 2dx Agentforce is the company’s platform for integrating AI agents into employee workflows, and Agentforce 2dx introduces new features that make it even easier for AI agents to be set up. Capabilities include a new API, the ability to embed Agentforce into Salesforce business logic, new integrations with MuleSoft, integration with the Slack Workflow Builder, new employee templates for Agentforce use cases, and more. Certain features have already begun rolling out, and Agentforce 2dx is expected to be fully available in April. “By extending digital labor beyond CRM, we’re making it easier than ever for businesses to embed agentic AI into any workflow or application to handle routine tasks, augment employees, and connect with customers,” said Adam Evans, EVP and GM of Salesforce’s AI Platform. “With deep integrations across Salesforce’s digital labor platform, CIOs, IT leaders, and developers can seamlessly build agents and automate work wherever it happens, driving efficiency, fueling innovation, and unlocking new opportunities in the $6 trillion digital labor market.” Sonatype announces AI Software Composition Analysis This end-to-end tool allows companies to protect and manage their models throughout development and deployment. It blocks malicious models from entering development environments, provides a centralized method for governance, automates policy management, and offers full visibility into model consumption. “No one knows open source like Sonatype, and AI is the next frontier. Just as we revolutionized open source security, we are now doing the same for AI,” said Mitchell Johnson, chief product development officer at Sonatype. Moderne launches AI agent for code refactoring Moderne is the creator of the open-source project, OpenRewrite, which automates mass code refactorings. The new AI agent, Moddy, has access to OpenRewrite’s capabilities, enabling developers to navigate, analyze, and modify large, multi-repository codebases. For instance, a developer could ask Moddy to describe the dependencies that are in use, upgrade frameworks, fix vulnerabilities, or locate specific business logic. Its Lossless Semantic Tree (LST) data model allows it to understand the structure, dependencies, and relationships across multiple repositories. “Moddy, the new multi-repo AI agent from Moderne, represents a paradigm shift in how enterprise codebases are managed, maintained, and modernized. It empowers developers to take command of their entire codebase—not just the code in their IDE,” Moderne wrote in a blog post. Google expands AI Overviews, adds AI Mode to Search The AI Overview feature now utilizes Gemini 2.0, allowing it to answer harder questions, such as those related to coding, math, or multimodal queries. AI Mode extends AI Overviews further by allowing users to ask follow-up questions when they get their response, rather than having to start multiple searches to get the information they’re looking for. For instance, a user could ask “what’s the difference in sleep tracking features between a smart ring, smartwatch and tracking mat,” and then ask a follow-up question: “what happens to your heart rate during deep sleep?” Amazon Bedrock Data Automation is now generally available First announced in preview during AWS re:Invent last year, Amazon Bedrock Data Automation streamlines the process of getting insights from unstructured, multimodal content, like documents, images, audio, and videos. “With Bedrock Data Automation, you can reduce the development time and effort to build intelligent document processing, media analysis, and other multimodal data-centric automation solutions,” the company wrote in a post. Currently, this feature is available in US East (N. Virginia) and US West (Oregon), and AWS plans to expand it to more regions in Europe and Asia later this year. Microsoft open sources Microsoft.Extensions.AI.Evalutions library This library provides a framework for evaluating the quality of AI applications, and it is now available as part of the dotnet/Extensions repository, which contains a number of libraries useful in creating production-ready applications. Along with the open source release, Microsoft is also providing a new set of samples to help developers get started with the library. The samples showcase common use cases and demonstrate how to leverage the library’s capabilities. OpenAI announces consortium for using AI to advance research and education NextGenAI is a collaboration between OpenAI and 15 research institutions to use AI to “accelerate research breakthroughs and transform education.” The participating institutions include Caltech, the California State University system, Duke University, the University of Georgia, Harvard University, Howard University, Massachusetts Institute of Technology, the University of Michigan, the University of Mississippi, The Ohio State University, the University of Oxford, Sciences Po, Texas A&M University, Boston Children’s Hospital, and the Boston Public Library. OpenAI is committing $50 million in research grants, compute funding, and API access to those organizations. “The field of AI wouldn’t be where it is today without decades of work in the academic community. Continued collaboration is essential to build AI that benefits everyone. NextGenAI will accelerate research progress and catalyze a new generation of institutions equipped to harness the transformative power of AI,” said Brad Lightcap, COO of OpenAI. Teradata launches new solution for efficiently handling vector data for agentic AI use cases Teradata, a provider of data analytics solutions, announced a new database offering for managing vector data. Teradata Enterprise Vector Store manages unstructured data in multi-modal formats like text, video, images, and PDFs. It can process billions of vectors and integrate them into pre-existing systems, and offers response times in the tens of milliseconds. According to the company, vector stores are an important foundation for agentic AI, but many vector stores require organizations to make tradeoffs, such as getting fast results, but only for small data sets, or being able to handle large vector volumes, but not at the speed required by agentic AI use cases. The post March 2025: All AI updates from the past month appeared first on SD Times.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  Mar 28, 2025: AI updates from the past week — Gemini 2.5, OpenAI 4o image generation, new reasoning agents from Microsoft, and more

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  • Latest News
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  • AI
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  • Akamai
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  • alexnet
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  • Google
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  • Microsoft
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  • OpenAI
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  • Red Hat

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  Software companies are constantly trying to add more and more AI features to their platforms, and AI companies are constantly releasing new models and features. It can be hard to keep up with it all, so we’ve written this roundup to share several notable updates around AI that software developers should know about.  Google releases … continue reading

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  The post Mar 28, 2025: AI updates from the past week — Gemini 2.5, OpenAI 4o image generation, new reasoning agents from Microsoft, and more appeared first on SD Times.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  Software companies are constantly trying to add more and more AI features to their platforms, and AI companies are constantly releasing new models and features. It can be hard to keep up with it all, so we’ve written this roundup to share several notable updates around AI that software developers should know about. Google releases reasoning model Gemini 2.5, its “most intelligent AI model” yet Gemini 2.0 Flash Thinking was the company’s first reasoning model, and Gemini 2.5 builds on that with a better base model and improved post-training. In its announcement, Google revealed that all of its future AI models will have reasoning capabilities built in. The first Gemini 2.5 model is Gemini 2.5 Pro Experimental, and it leads in LMArena benchmarks over other reasoning models like OpenAI o3-mini, Claude 3.5 Sonnet, and DeepSeek R1. “Gemini 2.5 models are thinking models, capable of reasoning through their thoughts before responding, resulting in enhanced performance and improved accuracy. In the field of AI, a system’s capacity for “reasoning” refers to more than just classification and prediction. It refers to its ability to analyze information, draw logical conclusions, incorporate context and nuance, and make informed decisions,” Koray Kavukcuoglu, CTO of Google DeepMind, wrote in a blog post. OpenAI announces 4o Image Generation The latest image generation model improves on text rendering, has the ability to refine images through multiple follow-up prompts, and offers better instruction following, with the ability to handle up to 10-20 different objects in a prompt. It can also perform in-context learning to analyze and learn from user-uploaded images, and the model also links its knowledge between text and images to generate better results. 4o image generation has begun rolling out for Plus, Pro, Team, and Free users as the default image generator, and access will soon be available for Enterprise and Edu users. Microsoft unveils new reasoning agents in Microsoft 365 Copilot The two agents, Researcher and Analyst, can help users analyze vast amounts of information, spanning emails, meetings, files, chats, and more. Researcher is ideal for multi-step research, such as building a go-to-market strategy based on both the context of a company’s work and broader competitive data found online. Beyond data in Microsoft 365, it can also leverage third-party connectors to bring in data from sources like Salesforce, ServiceNow, and Confluence. Analyst is designed for complex data analysis, such as turning raw data from multiple spreadsheets into a demand forecast for a new product or a visualization of customer purchasing patterns. These two agents will begin rolling out to Microsoft 365 Copilot subscribers starting in April as part of the Frontier early access program. Microsoft Security Copilot gets several new agents The new agents include a Phishing Triage Agent in Microsoft Defender, Alert Triage Agents in Microsoft Purview, Conditional Access Optimization Agent in Microsoft Entra, Vulnerability Remediation Agent in Microsoft Intune, and Threat Intelligence Briefing Agent in Security Copilot. The company also announced five additional agents from its Microsoft Security partners: Privacy Breach Response Agent by OneTrust, Network Supervisor Agent by Aviatrix, SecOps Tooling Agent by BlueVoyant, Alert Triage Agent by Tanium, and Task Optimizer Agent by Fletch. The agents will be available in preview starting in April. “Building on the transformative capabilities of Security Copilot, the six Microsoft Security Copilot agents enable teams to autonomously handle high-volume security and IT tasks while seamlessly integrating with Microsoft Security solutions. Purpose-built for security, agents learn from feedback, adapt to workflows, and operate securely—aligned to Microsoft’s Zero Trust framework. With security teams fully in control, agents accelerate responses, prioritize risks, and drive efficiency to enable proactive protection and strengthen an organization’s security posture,” Vasu Jakkal, corporate vice president of Microsoft Security, wrote in a blog post. Red Hat AI offers new capabilities across Red Hat OpenShift AI Red Hat OpenShift AI 2.18 adds new features such as distributed serving that allows IT teams to split model serving across multiple GPUs, an end-to-end model tuning experience across InstructLab and Red Hat OpenShift AI data science pipelines, and model evaluation. This release also includes a preview of AI Guardrails, which offer additional methods for identifying and mitigating “potentially hateful, abusive or profane speech, personally identifiable information, competitive information or other data limited by corporate policies.” Akamai launches new platform for AI inference at the edge Akamai has announced the launch of Akamai Cloud Inference, a new solution that provides tools for developers to build and run AI applications at the edge. According to Akamai, bringing data workloads closer to end users with this tool can result in 3x better throughput and reduce latency up to 2.5x. Akamai Cloud Inference offers a variety of compute types, from classic CPUs to GPUs to tailored ASIC VPUs. It offers integrations with Nvidia’s AI ecosystem, leveraging technologies such as Triton, TAO Toolkit, TensorRT, and NVFlare. Due to a partnership with VAST Data, the solution provides access to real-time data so that developers can accelerate inference-related tasks. The solution also offers highly scalable object storage and integration with vector database vendors like Aiven and Milvus. AlexNet source code is now open source AlexNet is a neural network for recognizing images that was created in 2012 by University of Toronto graduate students Alex Krizhevsky and Ilya Sutskever and their advisor Geoffrey Hinton. “Before AlexNet, almost none of the leading computer vision papers used neural nets. After it, almost all of them would. AlexNet was just the beginning. In the next decade, neural networks would advance to synthesize believable human voices, beat champion Go players, model human language, and generate artwork, culminating with the release of ChatGPT in 2022 by OpenAI, a company cofounded by Sutskever,” wrote Hansem Hsu, curator of the Computer History Museum Software History Center, the organization that is releasing the source code, in partnership with Google. The source code can be found here. Read last week’s AI announcements roundup here. The post Mar 28, 2025: AI updates from the past week — Gemini 2.5, OpenAI 4o image generation, new reasoning agents from Microsoft, and more appeared first on SD Times.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  Akamai launches new platform for AI inference at the edge

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  • Latest News
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  • AI
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  • Akamai

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  Akamai has announced the launch of Akamai Cloud Inference, a new solution that provides tools for developers to build and run AI applications at the edge. According to Akamai, bringing data workloads closer to end users with this tool can result in 3x better throughput and reduce latency up to 2.5x. “Training an LLM is … continue reading

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  The post Akamai launches new platform for AI inference at the edge appeared first on SD Times.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  Akamai has announced the launch of Akamai Cloud Inference, a new solution that provides tools for developers to build and run AI applications at the edge. According to Akamai, bringing data workloads closer to end users with this tool can result in 3x better throughput and reduce latency up to 2.5x. “Training an LLM is like creating a map, requiring you to gather data, analyze terrain, and plot routes,” said Adam Karon, chief operating officer and general manager of the Cloud Technology Group at Akamai. “It’s slow and resource-intensive, but once built, it’s highly useful. AI inference is like using a GPS, instantly applying that knowledge, recalculating in real time, and adapting to changes to get you where you need to go. Inference is the next frontier for AI.” Akamai Cloud Inference offers a variety of compute types, from classic CPUs to GPUs to tailored ASIC VPUs. It offers integrations with Nvidia’s AI ecosystem, leveraging technologies such as Triton, TAO Toolkit, TensorRT, and NVFlare. Due to a partnership with VAST Data, the solution also provides access to real-time data so that developers can accelerate inference-related tasks. The solution also offers highly scalable object storage and integration with vector database vendors like Aiven and Milvus. “With this data management stack, Akamai securely stores fine-tuned model data and training artifacts to deliver low-latency AI inference at global scale,” the company wrote in its announcement. It also offers capabilities for containerizing AI workloads, which is important for enabling demand-based autoscaling, improved application resilience, and hybrid/multicloud portability. And finally, the platform also includes WebAssembly capabilities to simplify how developers build AI applications. “While the heavy lifting of training LLMs will continue to happen in big hyperscale data centers, the actionable work of inferencing will take place at the edge where the platform Akamai has built over the past two and a half decades becomes vital for the future of AI and sets us apart from every other cloud provider in the market,” said Karon. The post Akamai launches new platform for AI inference at the edge appeared first on SD Times.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  Android team unveils upcoming enhancements to make Google Play safer

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  • Latest News
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  • Android
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  • Google
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  • mobile

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  The Android development team is announcing several upcoming updates that will make it easier for app developers to secure their applications. According to the team, security is a priority, and over the last few years it has made several improvements to how security and privacy are managed in Google Play, and recent updates over the … continue reading

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  The post Android team unveils upcoming enhancements to make Google Play safer appeared first on SD Times.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  The Android development team is announcing several upcoming updates that will make it easier for app developers to secure their applications. According to the team, security is a priority, and over the last few years it has made several improvements to how security and privacy are managed in Google Play, and recent updates over the last few years have included enhanced tools to protect against fraud, pre-review checks to fix policy and compliance issues earlier in the development life cycle, and advanced AI-powered threat detection capabilities. Building on those, some of the upcoming enhancements the Android team will be making this year include: More pre-review checks New ways to help developers understand Google Play policies, better navigation in the Policy Center, and new features in Console and Android Studio to allow developers to fix issues before app submission. Updates to the Play Integrity API that will better enable developers to deal with emerging threats New badges that will be added to store listings following the success of the “Government” and “Verified” badges “Knowing that you’re building on a safe, secure ecosystem is essential for any app developer. We continuously invest in protecting Android and Google Play, so millions of users around the world can trust the apps they download and you can build thriving businesses. And we’re dedicated to continually improving our developer tools to make world–class security even easier to implement,” Suzanne Frey, VP of product, trust, and growth for Android & Play, wrote in a blog post. RELATED CONTENT: Google releases reasoning model Gemini 2.5, its “most intelligent AI model” yet The post Android team unveils upcoming enhancements to make Google Play safer appeared first on SD Times.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  Spark your digital transformation with AI and VSM

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  • Latest News
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  • data integration
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  • product management
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  • Spark
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  • Value Stream Management

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  Spark. It’s what many organizations are finding that AI can do for their digital transformation efforts. It’s also the theme of the 2025 Broadcom Value Stream Summit, at which the company will present its strategies and tooling for delivery customer value and service.  The last major push for digital transformation was fueled by the COVID-19 … continue reading

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  The post Spark your digital transformation with AI and VSM appeared first on SD Times.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  Spark. It’s what many organizations are finding that AI can do for their digital transformation efforts. It’s also the theme of the 2025 Broadcom Value Stream Summit, at which the company will present its strategies and tooling for delivery customer value and service. The last major push for digital transformation was fueled by the COVID-19 pandemic, when organizations had to adopt remote for employees and students working from home. Since then, the progression toward transformation has been slow, but is steady. And now, explained Jean Louis Vignaud, head of ValueOps at Broadcom, “AI is going to … energize the need for transformation inside the organization.” This is where, Broadcom has said, “AI and VSM work in synergy – machine learning and GenAI augment the existing value drivers of visibility, alignment, and efficiency by delivering predictive insights, enhancing decision-making, and automating challenging or repetitive tasks.” Broadcom will discuss Vaia, its ValueOps AI agent, and how it delivers on that vision. As part of a digital transformation, Vignaud said organizations are looking at their offerings as products, rather than development projects. Along with that, value stream management brings a way to adjust how organizations work to become more efficient in the way they support their digital products. He noted that between 40% and 60% of businesses are still running projects. Vignaud believes that the incentive to move from projects to products has not been strong enough to overcome the resistance to cultural transformation that’s needed to make the move. “But,” he said, “the impact of AI is so big that the need for change will be significantly raised. And I do expect organizations to be moving forward and re-accelerating in that transformation because of AI.” The keynote will be delivered by Forrester VP, Principal Analyst Ted Schadler, who serves C-level technology executives with IT strategies that bring the full value of technology to businesses. His talk is, “AI Computing Will Change the World by Empowering People.” Also speaking will be Staci Cross, AVP, IT Strategy & Planning at Carnival Cruise Line, and Erin Fleckenstein, Office of the CTO / Chief of Staff at Ahold Delhaize USA, about their digital transformation and AI experiences. Themes of the Summit that attendees can look forward to are discussions on what comes next in VSM, how it will work together with AI, data integration and a look at real-world success stories. Highlights include case studies, strategic analysis of AI’s impact on delivering products and value, advice on best practices for VSM and product management, and exposure to thought leaders to discuss it all. The Value Stream Management Summit is set for April 30, from 11 a.m. to 2 p.m. Eastern time. The post Spark your digital transformation with AI and VSM appeared first on SD Times.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  Google releases reasoning model Gemini 2.5, its “most intelligent AI model” yet

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  • Latest News
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  • AI
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  • gemini
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  • Google

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  Google has announced the release of Gemini 2.5, which is a new reasoning model that the company claims is its “most intelligent AI model” yet. “Gemini 2.5 models are thinking models, capable of reasoning through their thoughts before responding, resulting in enhanced performance and improved accuracy. In the field of AI, a system’s capacity for … continue reading

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  The post Google releases reasoning model Gemini 2.5, its “most intelligent AI model” yet appeared first on SD Times.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  Google has announced the release of Gemini 2.5, which is a new reasoning model that the company claims is its “most intelligent AI model” yet. “Gemini 2.5 models are thinking models, capable of reasoning through their thoughts before responding, resulting in enhanced performance and improved accuracy. In the field of AI, a system’s capacity for “reasoning” refers to more than just classification and prediction. It refers to its ability to analyze information, draw logical conclusions, incorporate context and nuance, and make informed decisions,” Koray Kavukcuoglu, CTO of Google DeepMind, wrote in a blog post. Gemini 2.0 Flash Thinking was the company’s first reasoning model, and Gemini 2.5 builds on that with a better base model and improved post-training. In its announcement, Google revealed that all of its future AI models will have reasoning capabilities built in. RELATED CONTENT: Mar 21, 2025: AI updates from the past week — Anthropic web search, Gemini Canvas, new OpenAI audio models, and more The first Gemini 2.5 model is Gemini 2.5 Pro Experimental, and it leads in LMArena benchmarks significantly over other reasoning models like OpenAI o3-mini, Claude 3.5 Sonnet, and DeepSeek R1. It also scored 18.8% on Humanity’s Last Exam, which is “a dataset designed by hundreds of subject matter experts to capture the human frontier of knowledge and reasoning.” It also excels at coding, specifically creating web apps and agentic applications, and handling code transformation. For comparison, OpenAI o3-mini scored 14% and DeepSeek R1 scored 8.6%. This model is now available in Google AI Studio and in the Gemini app for Advanced subscribers. Google is working on adding it to Vertex AI as well, and in the next few weeks it will also announce pricing for the model. At launch, it offers a 1 million token context window, and the company is working on adding a 2 million token context window soon. The post Google releases reasoning model Gemini 2.5, its “most intelligent AI model” yet appeared first on SD Times.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  Instabug launches new observability features to connect business outcomes with app performance, user experience

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  • Latest News
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  • Instabug
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  • observability

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  The mobile observability company Instabug has announced new features that will help developers better monitor the user experience of their applications. The new features released today include: Frustration-Free Sessions, consolidating multiple frustration signals, like crashes, slow launches, and network failures, into a single metric to give development teams a clear way to measure and improve … continue reading

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  The post Instabug launches new observability features to connect business outcomes with app performance, user experience appeared first on SD Times.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  The mobile observability company Instabug has announced new features that will help developers better monitor the user experience of their applications. The new features released today include: Frustration-Free Sessions, consolidating multiple frustration signals, like crashes, slow launches, and network failures, into a single metric to give development teams a clear way to measure and improve user experience Business Impact Dashboard, which connects app performance to business outcomes so companies can make data-driven decisions Prioritized Issues List, which ranks issues based on how they impact user frustration and business metrics “For years, mobile teams have relied on incomplete metrics that fail to capture the full user experience,” said Kenny Johnston, chief product officer at Instabug. “With the launch of Frustration-Free Sessions, Business Impact Dashboard, and Prioritized Issues List, we are giving teams the capabilities they need to bridge the gap between visibility into the business impact of app quality issues and actually achieving that impact. This is a game-changer for mobile app teams.” The three new features are now available as part of Instabug’s performance monitoring and stability suite. The company will be demoing these new features during a webinar on April 10 at 1 PM ET | 10 AM PT. The post Instabug launches new observability features to connect business outcomes with app performance, user experience appeared first on SD Times.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  BrowserStack adds Private Devices offering to enabling testing across variety of secured devices

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  • Latest News
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  • BrowserStack
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  • test
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  • testing

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  The testing company BrowserStack has announced a new offering to help organizations get access to different devices to test their applications on. The new offering, Private Devices, provides access to real devices that are secured in data centers, which enables organizations to test on those devices without needing to compromise on security or performance. “With … continue reading

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  The post BrowserStack adds Private Devices offering to enabling testing across variety of secured devices appeared first on SD Times.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  The testing company BrowserStack has announced a new offering to help organizations get access to different devices to test their applications on. The new offering, Private Devices, provides access to real devices that are secured in data centers, which enables organizations to test on those devices without needing to compromise on security or performance. “With Private Devices, we’re addressing the critical needs of enterprise customers who require both advanced security and testing flexibility. With this launch, we’re giving large enterprises the control and resources they need for secure, flexible, and efficient testing,” said Nakul Aggarwal, CTO of BrowserStack. Devices have guaranteed availability, meaning organizations won’t need to queue their tests. Private Devices also offer persistent device setups that retain apps, accounts, and settings between sessions. The devices have advanced functionality, such as settings access, native apps, and iCloud functionality. Other key features include UDID access, fixed SIM cards and phone numbers, and isolated device access. “BrowserStack allows us to test our applications on real devices without worrying about the costs of procuring and maintaining the devices,” said Prabhu Maniraj, head of QA at UNiDAYS. The post BrowserStack adds Private Devices offering to enabling testing across variety of secured devices appeared first on SD Times.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  Kagent: Bringing agentic AI to cloud native

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  • Latest News
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  • agentic ai
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  • kagent
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  • KubeCon

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  Oh no! Your application is unreachable, buried under multiple connection hops. How do you pinpoint the broken link? How do you generate an alert or bug report from Prometheus when certain conditions are met?  You need to roll out a new version of your application. How do you execute a progressive rollout using Argo Rollouts? … continue reading

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  The post Kagent: Bringing agentic AI to cloud native appeared first on SD Times.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  Oh no! Your application is unreachable, buried under multiple connection hops. How do you pinpoint the broken link? How do you generate an alert or bug report from Prometheus when certain conditions are met? You need to roll out a new version of your application. How do you execute a progressive rollout using Argo Rollouts? How do you safely enable zero trust network security when your application scales beyond a single cluster or cloud? With so many projects in the cloud native ecosystem, how do you figure out which ones are right for your needs and layer them together with proper configuration management? Sound familiar? We hear these questions all the time from platform and DevOps engineers working with Cloud Native Computing Foundation (CNCF) projects like Kubernetes, Envoy, Istio, Prometheus, and Argo. So why not build AI agents to tackle common challenges and support engineers and customers? Why not create a catalog of AI agents for the cloud native ecosystem, enabling everyone to run, build and share AI-driven solutions? What is kagent? You’ve probably interacted with ChatGPT, an AI chatbot that provides natural language responses. Agentic AI, however, goes beyond simple chat interactions. It uses advanced reasoning and iterative planning to autonomously solve complex, non-deterministic multistep problems, turning insights into actions that enhance productivity. What if we applied agentic AI to the day-to-day operational challenges faced by cloud native engineers? That’s where kagent comes in. Kagent is an open source programming framework designed for DevOps and platform engineers to run AI agents in Kubernetes. It helps engineers build powerful internal platforms by tackling cloud native tasks such as configuration, troubleshooting, complex deployment scenarios, observability pipelines and dashboards, and safely enabling network security (like mTLS, authentication/authorization changes, etc). Recognizing that different users have different challenges, we designed kagent to be extensible—allowing DevOps engineers, platform teams, and tool developers to create and share their own AI agents. Built on Microsoft’s AutoGen open source framework, kagent provides a powerful foundation for AI-driven solutions in cloud native environments. Architecture of kagent Kagent is built on three key layers: Tools, Agents, and the Framework. Tools: Pre-defined functions that AI agents can use, such as sending emails, searching a database, displaying pod logs, or calling external APIs. Users can integrate Model Context Protocol (MCP) servers as tools or build custom tools. Agents: Autonomous systems capable of planning, executing tasks, analyzing results, and continuously improving outcomes. Agents utilize one or more tools to accomplish objectives. Framework: A simple interface to run agents via UI or declaratively. The framework is fully extensible, allowing users to develop new tools or agents, or extend the framework itself. Based on our experience, we’ve built tools to interact with Kubernetes, Prometheus, Istio, and Argo, along with AI agents to autonomously solve some of the most common cloud native problems. Join the kagent Community If you’re a platform or DevOps engineer, and leveraging AI agents to solve cloud native operation challenges excites you, or if you’re a developer or CNCF project maintainer interested in building AI agents to enrich our ecosystem, we’d love to collaborate! Check out our website and GitHub repository. Follow our getting started guide to experiment with AI agents in your Kubernetes cluster, and contribute your own agents and tools to extend the cloud native AI ecosystem. Join the discussion in the #kagent channel on CNCF Slack—we’d love to hear from you! We will also be at KubeCon + CloudNativeCon Europe in London from April 1-4 at the Solo.io booth if you are interested in discussing the project further. Let’s build the future of AI agents to solve cloud native operation challenges, together. The post Kagent: Bringing agentic AI to cloud native appeared first on SD Times.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  How to build a multi-agent orchestrator using Flink and Kafka

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  • Latest News

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  Just like some problems are too big for one person to solve, some tasks are too complex for a single AI agent. Instead, the best approach is to decompose problems into smaller, specialized units, where multiple agents work together as a team. This is the foundation of multi-agent systems. Networks of agents, each with specific … continue reading

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  The post How to build a multi-agent orchestrator using Flink and Kafka appeared first on SD Times.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  Just like some problems are too big for one person to solve, some tasks are too complex for a single AI agent. Instead, the best approach is to decompose problems into smaller, specialized units, where multiple agents work together as a team. This is the foundation of multi-agent systems. Networks of agents, each with specific roles, collaborating to solve larger problems. When building multi-agent systems, you need a way to coordinate how agents interact. If every agent talks to every other agent directly, things quickly become a tangled mess, making it hard to scale, and hard to debug. That’s where the orchestrator pattern comes in. Instead of agents making ad-hoc decisions about where to send messages, a central orchestrator acts as the parent node, deciding which agent should handle a given task based on context. The orchestrator takes in messages, interprets them, and routes them to the right agent at the right time. This makes the system dynamic, adaptable, and scalable. Think of it like a well-run dispatch center. Instead of individual responders deciding where to go, a central system evaluates incoming information and directs it efficiently. This ensures that agents don’t duplicate work or operate in isolation, but can collaborate effectively without hardcoded dependencies. In this article, I’ll walk through how to build an event-driven orchestrator for multi-agent systems using Apache Flink and Apache Kafka, leveraging Flink to interpret and route messages while using Kafka as the system’s short-term shared memory. Why Event-Driven Agents? At the core of any multi-agent system is how agents communicate. Request/response models, while simple to conceptualize, tend to break down when systems need to evolve, adapt to new information, or operate in unpredictable environments. That’s why event-driven messaging, powered by technologies like Apache Kafka and Apache Flink, is typically the better model for enterprise applications. Event-Driven Multi-Agent Communication An event-driven architecture allows agents to communicate dynamically without rigid dependencies, making them more autonomous and resilient. Instead of hardcoding relationships, agents react to events, enabling greater flexibility, parallelism, and fault tolerance. In the same way that event-driven architectures provide de-coupling for microservices and teams, they provide the same advantages when building a multi-agent system. An agent is essentially a stateful microservice with a brain, so many of the same patterns for building reliable distributed systems apply to agents as well. Additionally, stream governance can verify message structure, preventing malformed data from disrupting the system. This is often missing in existing multi-agent frameworks today, making event-driven architectures even more compelling. Orchestration: Coordinating Agentic Workflows In complex systems, agents rarely work in isolation. Real-world applications require multiple agents collaborating, handling distinct responsibilities while sharing context. This introduces challenges around task dependencies, failure recovery, and communication efficiency. The orchestrator pattern solves this by introducing a lead agent, or orchestrator, that directs other agents in problem-solving. Instead of static workflows like traditional microservices, agents generate dynamic execution plans, breaking down tasks and adapting in real time. The Orchestrator Agent Pattern This flexibility, however, creates challenges: Task Explosion – Agents can generate unbounded tasks, requiring resource management. Monitoring & Recovery – Agents need a way to track progress, catch failures, and re-plan. Scalability – The system must handle an increasing number of agent interactions without bottlenecks. This is where event-driven architectures shine. With a streaming backbone, agents can react to new data immediately, track dependencies efficiently, and recover from failures gracefully, all without centralized bottlenecks. Agentic systems are fundamentally dynamic, stateful, and adaptive—meaning event-driven architectures are a natural fit. In the rest of this article, I’ll break down a reference architecture for event-driven multi-agent systems, showing how to implement an orchestrator pattern using Apache Flink and Apache Kafka, powering real-time agent decision-making at scale. Multi-Agent Orchestration with Flink Building scalable multi-agent systems requires real-time decision-making and dynamic routing of messages between agents. This is where Apache Flink plays a crucial role. Apache Flink is a stream processing engine designed to handle stateful computations on unbounded streams of data. Unlike batch processing frameworks, Flink can process events in real time, making it an ideal tool for orchestrating multi-agent interactions. Revisiting the Orchestrator Pattern As discussed earlier, multi-agent systems need an orchestrator to decide which agent should handle a given task. Instead of agents making ad-hoc decisions, the orchestrator ingests messages, interprets them using an LLM, and routes them to the right agent. To support this orchestration pattern with Flink, Kafka is used as the messaging backbone and Flink is the processing engine: Powering Multi-Agent Orchestration with Flink Message Production: Agents produce messages to a Kafka topic. Each message contains the raw contextual data relevant to an agent. Flink Processing & Routing: A Flink job listens to new messages in Kafka. The message is passed to an LLM, which determines the most appropriate agent to handle it. The LLM’s decision is based on a structured Agent Definition, which includes: Agent Name – Unique identifier for the agent. Description – The agent’s primary function. Input – Expected data format the agent processes enforced by a data contract. Output – The result the agent generates. Decision Output and Routing: Once the LLM selects the appropriate agent, Flink publishes the message to an HTTP endpoint associated with the identified agent. Agent Execution & Continuation: The agent processes the message and writes updates back to the agent messages topic. The Flink job detects these updates, reevaluates if additional processing is required, and continues routing messages until the agent workflow is complete. Closing the Loop This event-driven feedback loop allows multi-agent systems to function autonomously and efficiently, ensuring: Real-time decision-making with no hardcoded workflows. Scalable execution with decentralized agent interactions. Seamless adaptability to new inputs and system changes. In the next section, we’ll walk through an example implementation of this architecture, including Flink job definitions, Kafka topics, and LLM-based decision-making. Building an Event-Driven Multi-Agent System: A Hands-On Implementation In previous sections, we explored the orchestrator pattern and why event-driven architectures are essential for scaling multi-agent systems. Now, we’ll show how this architecture works by walking through a real-world use case: an AI-driven sales development representative (SDR) system that autonomously manages leads. Event-Driven AI Based SDR using a Multi-Agent System To implement this system, we utilize Confluent Cloud, a fully managed service for Apache Kafka and Flink. The AI SDR Multi-Agent System The system consists of multiple specialized agents that handle different stages of the lead qualification and engagement process. Each agent has a defined role and operates independently within an event-driven pipeline. Agents in the AI SDR System Lead Ingestion Agent: Captures raw lead data, enriches it with additional research, and generates a lead profile. Lead Scoring Agent: Analyzes lead data to assign a priority score and determine the best engagement strategy. Active Outreach Agent: Uses lead details and scores to generate personalized outreach messages. Nurture Campaign Agent: Dynamically creates a sequence of emails based on where the lead originated and what their interest was. Send Email Agent: Takes in emails and sets up the campaign to send them. The agents have no explicit dependencies on each other. They simply produce and consume events independently. How Orchestration Works in Flink SQL To determine which agent should process an incoming message, the orchestrator uses external model inference in Flink. This model receives the message, evaluates its content, and assigns it to the correct agent based on predefined functions. The Flink SQL statement to set up the model is shown below with an abbreviated version of the prompt used for performing the mapping operation. After creating the model, we create a Flink job that uses this model to process incoming messages and assign them to the correct agent: This automatically routes messages to the appropriate agent, ensuring a seamless, intelligent workflow. Each agent processes its task and writes updates back to Kafka, allowing the next agent in the pipeline to take action. Executing Outreach In the demo application, leads are written from a website into MongoDB. A source connector for MongoDB sends the leads into an incoming leads topic, where they are copied into the agent messages topic. This action kick starts the AI SDR automated process. The query above shows that all decision making and evaluation is left to the orchestrator with no routing logic hard-coded. The LLM is reasoning on the best action to take based upon agent descriptions and the payloads routed through the agent messages topic. In this way, we’ve built an orchestrator with only a few lines of code with the heavy lifting done by the LLM. Wrapping Up: The Future of Event-Driven Multi-Agent Systems The AI SDR system we’ve explored demonstrates how event-driven architectures enable multi-agent systems to operate efficiently, making real-time decisions without rigid workflows. By leveraging Flink for message processing and routing and Kafka for short-term shared memory, we achieve a scalable, autonomous orchestration framework that allows agents to collaborate dynamically. The key takeaway is that agents are essentially stateful microservices with a brain, and the same event-driven principles that scaled microservices apply to multi-agent systems. Instead of static, predefined workflows, we enable systems and teams to be de-coupled, adapt dynamically, reacting to new data as it arrives. While this blog post focused on the orchestrator pattern, it’s important to note that other patterns can be supported as well. In some cases, more explicit dependencies between agents are necessary to ensure reliability, consistency, or domain-specific constraints. For example, certain workflows may require a strict sequence of agent execution to guarantee transactional integrity or regulatory compliance. The key is finding the right balance between flexibility and control depending on the application’s needs. If you’re interested in building your own event-driven agent system, check out the GitHub repository for the full implementation, including Flink SQL examples and Kafka configurations. The post How to build a multi-agent orchestrator using Flink and Kafka appeared first on SD Times.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  Recent content in Articles on Smashing Magazine — For Web Designers And Developers

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  Blossoms, Flowers, And The Magic Of Spring (April 2025 Wallpapers Edition)

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    The beginning of the new month is the perfect opportunity to give your desktop a makeover. If you’re looking for some beautiful and unique wallpapers to cater for a bit of inspiration this April, well, this post has got you covered.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    Starting the new month with a little inspiration boost — that’s the idea behind our monthly wallpapers series which has been going on for more than fourteen years already. Each month, the wallpapers are created by the community for the community, and everyone who has an idea for a design is welcome to join in — experienced designers just like aspiring artists. Of course, it wasn’t any different this time around. For this edition, creative folks from all across the globe once again got their ideas flowing to bring some good vibes to your screens. You’ll find their wallpapers compiled below, along with a selection of timeless April favorites from our archives that are just too good to be forgotten. A huge thank-you to everyone who shared their designs with us this month — you’re smashing! If you too would like to get featured in one of our upcoming wallpapers posts, please don’t hesitate to submit your design. We can’t wait to see what you’ll come up with! Happy April! You can click on every image to see a larger preview. We respect and carefully consider the ideas and motivation behind each and every artist’s work. This is why we give all artists the full freedom to explore their creativity and express emotions and experience through their works. This is also why the themes of the wallpapers weren’t anyhow influenced by us but rather designed from scratch by the artists themselves. April Blooms And Easter Joy “April bursts with color, joy, and the magic of new beginnings. As spring awakens, Easter fills the air with wonder — bunnies paint playful masterpieces on eggs, and laughter weaves through cherished traditions. It’s a season to embrace warmth, kindness, and the simple beauty of blooming days.” — Designed by LibraFire from Serbia. preview with calendar: 320x480, 640x480, 800x480, 800x600, 1024x768, 1024x1024, 1152x864, 1280x720, 1280x800, 1280x960, 1280x1024, 1400x1050, 1440x900, 1600x1200, 1680x1050, 1680x1200, 1920x1080, 1920x1200, 1920x1440, 2560x1440 without calendar: 320x480, 640x480, 800x480, 800x600, 1024x768, 1024x1024, 1152x864, 1280x720, 1280x800, 1280x960, 1280x1024, 1400x1050, 1440x900, 1600x1200, 1680x1050, 1680x1200, 1920x1080, 1920x1200, 1920x1440, 2560x1440 Walking Among Chimpanzees “It’s April, and we’re heading to Tanzania with Jane Goodall, her chimpanzees, and her reflection that we are all important: ‘Every individual matters. Every individual has a role to play. Every individual makes a difference.” — Designed by Veronica Valenzuela from Spain. preview with calendar: 640x480, 800x480, 1024x768, 1280x720, 1280x800, 1440x900, 1600x1200, 1920x1080, 1920x1440, 2560x1440 without calendar: 640x480, 800x480, 1024x768, 1280x720, 1280x800, 1440x900, 1600x1200, 1920x1080, 1920x1440, 2560x1440 Eggcited Designed by Ricardo Gimenes from Spain. preview with calendar: 640x480, 800x480, 800x600, 1024x768, 1024x1024, 1152x864, 1280x720, 1280x800, 1280x960, 1280x1024, 1366x768, 1400x1050, 1440x900, 1600x1200, 1680x1050, 1680x1200, 1920x1080, 1920x1200, 1920x1440, 2560x1440, 3840x2160 without calendar: 640x480, 800x480, 800x600, 1024x768, 1024x1024, 1152x864, 1280x720, 1280x800, 1280x960, 1280x1024, 1366x768, 1400x1050, 1440x900, 1600x1200, 1680x1050, 1680x1200, 1920x1080, 1920x1200, 1920x1440, 2560x1440, 3840x2160 2001 Designed by Ricardo Gimenes from Spain. preview with calendar: 640x480, 800x480, 800x600, 1024x768, 1024x1024, 1152x864, 1280x720, 1280x800, 1280x960, 1280x1024, 1366x768, 1400x1050, 1440x900, 1600x1200, 1680x1050, 1680x1200, 1920x1080, 1920x1200, 1920x1440, 2560x1440, 3840x2160 without calendar: 640x480, 800x480, 800x600, 1024x768, 1024x1024, 1152x864, 1280x720, 1280x800, 1280x960, 1280x1024, 1366x768, 1400x1050, 1440x900, 1600x1200, 1680x1050, 1680x1200, 1920x1080, 1920x1200, 1920x1440, 2560x1440, 3840x2160 Swing Into Spring “Our April calendar needs not mark any special occasion — April itself is a reason to celebrate. It was a breeze creating this minimal, pastel-colored calendar design with a custom lettering font and plant pattern for the ultimate spring feel.” — Designed by PopArt Studio from Serbia. preview 320x480, 640x480, 800x480, 800x600, 1024x768, 1024x1024, 1152x864, 1280x720, 1280x800, 1280x960, 1280x1024, 1400x1050, 1440x900, 1600x1200, 1680x1050, 1680x1200, 1920x1080, 1920x1200, 1920x1440, 2560x1440 Spring Awakens “We all look forward to the awakening of a life that spreads its wings after a dormant winter and opens its petals to greet us. Long live spring, long live life.” — Designed by LibraFire from Serbia. preview 320x480, 640x480, 800x480, 800x600, 1024x768, 1024x1024, 1152x864, 1280x720, 1280x800, 1280x960, 1280x1024, 1366x768, 1400x1050, 1440x900, 1600x1200, 1680x1050, 1680x1200, 1920x1080, 1920x1200, 1920x1440, 2560x1440 Inspiring Blossom “‘Sweet spring is your time is my time is our time for springtime is lovetime and viva sweet love,’ wrote E. E. Cummings. And we have a question for you: Is there anything more refreshing, reviving, and recharging than nature in blossom? Let it inspire us all to rise up, hold our heads high, and show the world what we are made of.” — Designed by PopArt Studio from Serbia. preview 320x480, 640x480, 800x480, 800x600, 1024x768, 1024x1024, 1152x864, 1280x720, 1280x800, 1280x960, 1280x1024, 1366x768, 1400x1050, 1440x900, 1600x1200, 1680x1050, 1680x1200, 1920x1080, 1920x1200, 1920x1440, 2560x1440 Dreaming “The moment when you just walk and your imagination fills up your mind with thoughts.” — Designed by Gal Shir from Israel. preview 340x480, 640x480, 800x480, 800x600, 1024x768, 1024x1024, 1152x864, 1280x720, 1280x800, 1280x960, 1280x1024, 1366x768, 1400x1050, 1440x900, 1600x1200, 1680x1050, 1680x1200, 1920x1080, 1920x1200, 1920x1440, 2560x1440 Clover Field Designed by Nathalie Ouederni from France. preview 1024x768, 1280x1024, 1440x900, 1680x1200, 1920x1200, 2560x1440 Rainy Day Designed by Xenia Latii from Berlin, Germany. preview 320x480, 640x480, 800x480, 800x600, 1024x768, 1152x864, 1280x720, 1280x800, 1280x960, 1280x1024, 1366x768, 1400x1050, 1440x900, 1600x1200, 1680x1050, 1680x1200, 1920x1080, 1920x1200, 1920x1440, 2560x1440 A Time For Reflection “‘We’re all equal before a wave.’ (Laird Hamilton)” — Designed by Shawna Armstrong from the United States. preview 1440x900, 1600x1200, 1680x1050, 1920x1080, 1920x1200, 1920x1440, 2560x1440 Purple Rain “This month is International Guitar Month! Time to get out your guitar and play. As a graphic designer/illustrator seeing all the variations of guitar shapes begs to be used for a fun design. Search the guitar shapes represented and see if you see one similar to yours, or see if you can identify some of the different styles that some famous guitarists have played (BTW, Prince’s guitar is in there and purple is just a cool color).” — Designed by Karen Frolo from the United States. preview 1024x768, 1024x1024, 1280x800, 1280x960, 1280x1024, 1366x768, 1440x900, 1600x1200, 1680x1050, 1680x1200, 1920x1080, 1920x1200, 1920x1440, 2560x1440 Wildest Dreams “We love the art direction, story, and overall cinematography of the ‘Wildest Dreams’ music video by Taylor Swift. It inspired us to create this illustration. Hope it will look good on your desktops.” — Designed by Kasra Design from Malaysia. preview 320x480, 640x480, 800x480, 800x600, 1024x768, 1024x1024, 1152x864, 1280x720, 1280x800, 1280x960, 1280x1024, 1366x768, 1400x1050, 1440x900, 1600x1200, 1680x1050, 1680x1200, 1920x1080, 1920x1200, 1920x1440, 2560x1440 Sakura “Spring is finally here with its sweet Sakura flowers, which remind me of my trip to Japan.” — Designed by Laurence Vagner from France. preview 1280x800, 1280x1024, 1680x1050, 1920x1080, 1920x1200, 2560x1440 April Fox Designed by MasterBundles from the United States. preview 1600x1200, 1680x1050, 1680x1200, 1920x1080, 1920x1200, 1920x1440, 2560x1440 Fairytale “A tribute to Hans Christian Andersen. Happy Birthday!” — Designed by Roxi Nastase from Romania. preview 1152x864, 1280x720, 1280x800, 1280x960, 1280x1024, 1400x1050, 1440x900, 1600x1200, 1680x1050, 1680x1200, 1920x1080, 1920x1200, 1920x1440, 2560x1440 Coffee Morning Designed by Ricardo Gimenes from Spain. preview 640x480, 800x480, 800x600, 1024x768, 1024x1024, 1152x864, 1280x720, 1280x800, 1280x960, 1280x1024, 1366x768, 1400x1050, 1440x900, 1600x1200, 1680x1050, 1680x1200, 1920x1080, 1920x1200, 1920x1440, 2560x1440, 3840x2160 The Loneliest House In The World “March 26 was Solitude Day. To celebrate it, here is the picture about the loneliest house in the world. It is a real house, I found it on Youtube.” — Designed by Vlad Gerasimov from Georgia. preview 800x480, 800x600, 1024x600, 1024x768, 1152x864, 1280x720, 1280x800, 1280x960, 1280x1024, 1366x768, 1400x1050, 1440x900, 1440x960, 1600x900, 1600x1200, 1680x1050, 1680x1200, 1920x1080, 1920x1200, 1920x1440, 2560x1440, 2560x1600, 2880x1800, 3072x1920, 3840x2160, 5120x2880 The Perpetual Circle “Inspired by the Black Forest, which is beginning right behind our office windows, so we can watch the perpetual circle of nature when we take a look outside.” — Designed by Nils Kunath from Germany. preview 320x480, 640x480, 1024x768, 1152x864, 1280x720, 1280x800, 1280x960, 1280x1024, 1400x1050, 1440x900, 1600x1200, 1680x1200, 1920x1080, 1920x1200, 1920x1440, 2560x1440 Ready For April “It is very common that it rains in April. This year, I am not sure… But whatever… we are just prepared!” — Designed by Verónica Valenzuela from Spain. preview 800x480, 1024x768, 1152x864, 1280x800, 1280x960, 1440x900, 1680x1200, 1920x1080, 2560x1440 Happy Easter Designed by Tazi Design from Australia. preview 320x480, 640x480, 800x600, 1024x768, 1152x864, 1280x720, 1280x960, 1600x1200, 1920x1080, 1920x1440, 2560x1440 In The River “Spring is here! Crocodiles search the hot and stay in the river.” — Designed by Veronica Valenzuela from Spain. preview 640x480, 800x480, 1024x768, 1280x720, 1280x800, 1440x900, 1600x1200, 1920x1080, 1920x1440, 2560x1440 Springtime Sage “Spring and fresh herbs always feel like they compliment each other. Keeping it light and fresh with this wallpaper welcomes a new season!” — Designed by Susan Chiang from the United States. preview 320x480, 1024x768, 1280x800, 1280x1024, 1400x900, 1680x1200, 1920x1200, 1920x1440 Citrus Passion Designed by Nathalie Ouederni from France. preview 320x480, 1024x768, 1200x1024, 1440x900, 1600x1200, 1680x1200, 1920x1200, 2560x1440 Walking To The Wizard “We walked to Oz with our friends. The road is long, but we follow the yellow bricks. Are you coming with us?” — Designed by Veronica Valenzuela from Spain. preview 640x480, 800x480, 1024x768, 1280x720, 1280x800, 1440x900, 1600x1200, 1920x1080, 1920x1440, 2560x1440 Hello! Designed by Rachel from the United States. preview 640x1136, 1080x1920, 1280x800, 1280x960, 1366x768, 1440x900, 1600x900, 1680x1200, 1920x1080, 1920x1200, 2048x2048, 2560x1440 Oceanic Wonders “Celebrate National Dolphin Day on April 14th by acknowledging the captivating beauty and importance of dolphins in our oceans!” — Designed by PopArt Studio from Serbia. preview 320x480, 640x480, 800x480, 800x600, 1024x768, 1024x1024, 1152x864, 1280x720, 1280x800, 1280x960, 1280x1024, 1400x1050, 1440x900, 1600x1200, 1680x1050, 1680x1200, 1920x1080, 1920x1200, 1920x1440, 2560x1440 Playful Alien “Everything would be more fun if a little alien had the controllers.” — Designed by Maria Keller from Mexico. preview 320x480, 640x480, 640x1136, 750x1334, 800x600, 1024x768, 1024x1024, 1152x864, 1242x2208, 1280x720, 1280x800, 1280x960, 1280x1024, 1366x768, 1400x1050, 1440x900, 1600x1200, 1680x1050, 1680x1200, 1920x1080, 1920x1200, 1920x1440, 2560x1440, 2880x1800 Good Day “Some pretty flowers and spring time always make for a good day.” — Designed by Amalia Van Bloom from the United States. preview 640x1136, 1024x768, 1280x800, 1280x1024, 1440x900, 1920x1200, 2560x1440 April Showers Designed by Ricardo Gimenes from Spain. preview 320x480, 640x480, 800x480, 800x600, 1024x768, 1024x1024, 1152x864, 1280x720, 1280x800, 1280x960, 1280x1024, 1366x768, 1400x1050, 1440x900, 1600x1200, 1680x1050, 1680x1200, 1920x1080, 1920x1200, 1920x1440, 2560x1440 Fusion Designed by Rio Creativo from Poland. preview 1280x800, 1680x1050, 1920x1080, 1920x1200, 2560x1440 Do Doodling Designed by Design Studio from India. preview 1440x900, 1600x1200, 1680x1050, 1680x1200, 1920x1080, 1920x1200, 1920x1440, 2560x1440 Ipoh Hor Fun “Missing my hometown’s delicious ‘Kai See Hor Fun’ (in Cantonese) that literally translates to ‘Shredded Chicken Flat Rice Noodles’. It is served in a clear chicken and prawn soup with chicken shreds, prawns, spring onions, and noodles.” — Designed by Lew Su Ann from Brunei. preview 640x480, 800x600, 1024x768, 1152x864, 1280x720, 1280x800, 1280x960, 1366x768, 1400x1050, 1440x900, 1600x1200, 1680x1050, 1920x1080, 1920x1200, 1920x1440

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    How To Argue Against AI-First Research

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      Companies have been turning their attention to “synthetic,” AI-driven user testing. However, as convenient as it might seem, it’s dangerous, expensive, and usually diminishes user value. Let’s take a closer look at why exactly it is problematic and how we can argue against it to make a case for UX research with real users. Part of [Smart Interface Design Patterns](https://smart-interface-design-patterns.com) by yours truly.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      With AI upon us, companies have recently been turning their attention to “synthetic” user testing — AI-driven research that replaces UX research. There, questions are answered by AI-generated “customers,” human tasks “performed” by AI agents. However, it’s not just for desk research or discovery that AI is used for; it’s an actual usability testing with “AI personas” that mimic human behavior of actual customers within the actual product. It’s like UX research, just… well, without the users. If this sounds worrying, confusing, and outlandish, it is — but this doesn’t stop companies from adopting AI “research” to drive business decisions. Although, unsurprisingly, the undertaking can be dangerous, risky, and expensive and usually diminishes user value. This article is part of our ongoing series on UX. You can find more details on design patterns and UX strategy in Smart Interface Design Patterns 🍣 — with live UX training coming up soon. Free preview. Fast, Cheap, Easy… And Imaginary Erika Hall famously noted that “design is only as ‘human-centered’ as the business model allows.” If a company is heavily driven by hunches, assumptions, and strong opinions, there will be little to no interest in properly-done UX research in the first place. But unlike UX research, AI research (conveniently called synthetic testing) is fast, cheap, and easy to re-run. It doesn’t raise uncomfortable questions, and it doesn’t flag wrong assumptions. It doesn’t require user recruitment, much time, or long-winded debates. And: it can manage thousands of AI personas at once. By studying AI-generated output, we can discover common journeys, navigation patterns, and common expectations. We can anticipate how people behave and what they would do. Well, that’s the big promise. And that’s where we start running into big problems. LLMs Are People Pleasers Good UX research has roots in what actually happened, not what might have happened or what might happen in the future. By nature, LLMs are trained to provide the most “plausible” or most likely output based on patterns captured in its training data. These patterns, however, emerge from expected behaviors by statistically “average” profiles extracted from content on the web. But these people don’t exist, they never have. By default, user segments are not scoped and not curated. They don’t represent the customer base of any product. So to be useful, we must eloquently prompt AI by explaining who users are, what they do, and how they behave. Otherwise, the output won’t match user needs and won’t apply to our users. When “producing” user insights, LLMs can’t generate unexpected things beyond what we’re already asking about. In comparison, researchers are only able to define what’s relevant as the process unfolds. In actual user testing, insights can help shift priorities or radically reimagine the problem we’re trying to solve, as well as potential business outcomes. Real insights come from unexpected behavior, from reading behavioral clues and emotions, from observing a person doing the opposite of what they said. We can’t replicate it with LLMs. AI User Research Isn’t “Better Than Nothing” Pavel Samsonov articulates that things that sound like customers might say them are worthless. But things that customers actually have said, done, or experienced carry inherent value (although they could be exaggerated). We just need to interpret them correctly. AI user research isn’t “better than nothing” or “more effective.” It creates an illusion of customer experiences that never happened and are at best good guesses but at worst misleading and non-applicable. Relying on AI-generated “insights” alone isn’t much different than reading tea leaves. The Cost Of Mechanical Decisions We often hear about the breakthrough of automation and knowledge generation with AI. Yet we often forget that automation often comes at a cost: the cost of mechanical decisions that are typically indiscriminate, favor uniformity, and erode quality. As Maria Rosala and Kate Moran write, the problem with AI research is that it most certainly will be misrepresentative, and without real research, you won't catch and correct those inaccuracies. Making decisions without talking to real customers is dangerous, harmful, and expensive. Beyond that, synthetic testing assumes that people fit in well-defined boxes, which is rarely true. Human behavior is shaped by our experiences, situations, habits that can’t be replicated by text generation alone. AI strengthens biases, supports hunches, and amplifies stereotypes. Triangulate Insights Instead Of Verifying Them Of course AI can provide useful starting points to explore early in the process. But inherently it also invites false impressions and unverified conclusions — presented with an incredible level of confidence and certainty. Starting with human research conducted with real customers using a real product is just much more reliable. After doing so, we can still apply AI to see if we perhaps missed something critical in user interviews. AI can enhance but not replace UX research. Also, when we do use AI for desk research, it can be tempting to try to “validate” AI “insights” with actual user testing. However, once we plant a seed of insight in our head, it’s easy to recognize its signs everywhere — even if it really isn’t there. Instead, we study actual customers, then triangulate data: track clusters or most heavily trafficked parts of the product. It might be that analytics and AI desk research confirm your hypothesis. That would give you a much stronger standing to move forward in the process. Wrapping Up I might sound like a broken record, but I keep wondering why we feel the urgency to replace UX work with automated AI tools. Good design requires a good amount of critical thinking, observation, and planning. To me personally, cleaning up after AI-generated output takes way more time than doing the actual work. There is an incredible value in talking to people who actually use your product. I would always choose one day with a real customer instead of one hour with 1,000 synthetic users pretending to be humans. Useful Resources Synthetic Users, by Maria Rosala, Kate Moran Synthetic Users: The Next Revolution in UX Research?, by Carolina Guimarães AI Users Are Neither AI Nor Users, by Debbie Levitt Planning Research with Generative AI, by Maria Rosala Synthetic Testing, by Stéphanie Walter, Nikki Anderson, MA The Dark Side of Synthetic AI Research, by Greg Nudelman New: How To Measure UX And Design Impact Meet Measure UX & Design Impact (8h), a new practical guide for designers and UX leads to measure and show your UX impact on business. Use the code 🎟 IMPACT to save 20% off today. Jump to the details. Video + UX Training Video only Video + UX Training $ 495.00 $ 799.00 Get Video + UX Training 25 video lessons (8h) + Live UX Training. 100 days money-back-guarantee. Video only $ 250.00$ 395.00 Get the video course 25 video lessons (8h). Updated yearly. Also available as a UX Bundle with 2 video courses.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      Adaptive Video Streaming With Dash.js In React

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        HTML `` is the de facto element we turn to for embedding video content, but it comes with constraints. For example, it downloads the video file linearly over HTTP, which leads to performance hiccups, especially for large videos consumed on slower connections. But with adaptive bitrate streaming, we can split the video into multiple segments at different bitrates and resolutions.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        I was recently tasked with creating video reels that needed to be played smoothly under a slow network or on low-end devices. I started with the native HTML5 <video> tag but quickly hit a wall — it just doesn’t cut it when connections are slow or devices are underpowered. After some research, I found that adaptive bitrate streaming was the solution I needed. But here’s the frustrating part: finding a comprehensive, beginner-friendly guide was so difficult. The resources on MDN and other websites were helpful but lacked the end-to-end tutorial I was looking for. That’s why I’m writing this article: to provide you with the step-by-step guide I wish I had found. I’ll bridge the gap between writing FFmpeg scripts, encoding video files, and implementing the DASH-compatible video player (Dash.js) with code examples you can follow. Going Beyond The Native HTML5 <video> Tag You might be wondering why you can’t simply rely on the HTML <video> element. There’s a good reason for that. Let’s compare the difference between a native <video> element and adaptive video streaming in browsers. Progressive Download With progressive downloading, your browser downloads the video file linearly from the server over HTTP and starts playback as long as it has buffered enough data. This is the default behavior of the <video> element. <video src="rabbit320.mp4" /> When you play the video, check your browser’s network tab, and you’ll see multiple requests with the 206 Partial Content status code. It uses HTTP 206 Range Requests to fetch the video file in chunks. The server sends specific byte ranges of the video to your browser. When you seek, the browser will make more range requests asking for new byte ranges (e.g., “Give me bytes 1,000,000–2,000,000”). In other words, it doesn’t fetch the entire file all at once. Instead, it delivers partial byte ranges from the single MP4 video file on demand. This is still considered a progressive download because only a single file is fetched over HTTP — there is no bandwidth or quality adaptation. If the server or browser doesn’t support range requests, the entire video file will be downloaded in a single request, returning a 200 OK status code. In that case, the video can only begin playing once the entire file has finished downloading. The problems? If you’re on a slow connection trying to watch high-resolution video, you’ll be waiting a long time before playback starts. Adaptive Bitrate Streaming Instead of serving one single video file, adaptive bitrate (ABR) streaming splits the video into multiple segments at different bitrates and resolutions. During playback, the ABR algorithm will automatically select the highest quality segment that can be downloaded in time for smooth playback based on your network connectivity, bandwidth, and other device capabilities. It continues adjusting throughout to adapt to changing conditions. This magic happens through two key browser technologies: Media Source Extension (MSE) It allows passing a MediaSource object to the src attribute in <video>, enabling sending multiple SourceBuffer objects that represent video segments. <video src="blob:https://example.com/6e31fe2a-a0a8-43f9-b415-73dc02985892" /> Media Capabilities API It provides information on your device’s video decoding and encoding abilities, enabling ABR to make informed decisions about which resolution to deliver. Together, they enable the core functionality of ABR, serving video chunks optimized for your specific device limitations in real time. Streaming Protocols: MPEG-DASH Vs. HLS As mentioned above, to stream media adaptively, a video is split into chunks at different quality levels across various time points. We need to facilitate the process of switching between these segments adaptively in real time. To achieve this, ABR streaming relies on specific protocols. The two most common ABR protocols are: MPEG-DASH, HTTP Live Streaming (HLS). Both of these protocols utilize HTTP to send video files. Hence, they are compatible with HTTP web servers. This article focuses on MPEG-DASH. However, it’s worth noting that DASH isn’t supported by Apple devices or browsers, as mentioned in Mux’s article. MPEG-DASH MPEG-DASH enables adaptive streaming through: A Media Presentation Description (MPD) file This XML manifest file contains information on how to select and manage streams based on adaptive rules. Segmented Media Files Video and audio files are divided into segments at different resolutions and durations using MPEG-DASH-compliant codecs and formats. On the client side, a DASH-compliant video player reads the MPD file and continuously monitors network bandwidth. Based on available bandwidth, the player selects the appropriate bitrate and requests the corresponding video chunk. This process repeats throughout playback, ensuring smooth, optimal quality. Now that you understand the fundamentals, let’s build our adaptive video player! Steps To Build an Adaptive Bitrate Streaming Video Player Here’s the plan: Transcode the MP4 video into audio and video renditions at different resolutions and bitrates with FFmpeg. Generate an MPD file with FFmpeg. Serve the output files from the server. Build the DASH-compatible video player to play the video. Install FFmpeg For macOS users, install FFmpeg using Brew by running the following command in your terminal: brew install ffmpeg For other operating systems, please refer to FFmpeg’s documentation. Generate Audio Rendition Next, run the following script to extract the audio track and encode it in WebM format for DASH compatibility: ffmpeg -i "input_video.mp4" -vn -acodec libvorbis -ab 128k "audio.webm" -i "input_video.mp4": Specifies the input video file. -vn: Disables the video stream (audio-only output). -acodec libvorbis: Uses the libvorbis codec to encode audio. -ab 128k: Sets the audio bitrate to 128 kbps. "audio.webm": Specifies the output audio file in WebM format. Generate Video Renditions Run this script to create three video renditions with varying resolutions and bitrates. The largest resolution should match the input file size. For example, if the input video is 576×1024 at 30 frames per second (fps), the script generates renditions optimized for vertical video playback. ffmpeg -i "input_video.mp4" -c:v libvpx-vp9 -keyint_min 150 -g 150 \ -tile-columns 4 -frame-parallel 1 -f webm \ -an -vf scale=576:1024 -b:v 1500k "input_video_576x1024_1500k.webm" \ -an -vf scale=480:854 -b:v 1000k "input_video_480x854_1000k.webm" \ -an -vf scale=360:640 -b:v 750k "input_video_360x640_750k.webm" -c:v libvpx-vp9: Uses the libvpx-vp9 as the VP9 video encoder for WebM. -keyint_min 150 and -g 150: Set a 150-frame keyframe interval (approximately every 5 seconds at 30 fps). This allows bitrate switching every 5 seconds. -tile-columns 4 and -frame-parallel 1: Optimize encoding performance through parallel processing. -f webm: Specifies the output format as WebM. In each rendition: -an: Excludes audio (video-only output). -vf scale=576:1024: Scales the video to a resolution of 576x1024 pixels. -b:v 1500k: Sets the video bitrate to 1500 kbps. WebM is chosen as the output format, as they are smaller in size and optimized yet widely compatible with most web browsers. Generate MPD Manifest File Combine the video renditions and audio track into a DASH-compliant MPD manifest file by running the following script: ffmpeg \ -f webm_dash_manifest -i "input_video_576x1024_1500k.webm" \ -f webm_dash_manifest -i "input_video_480x854_1000k.webm" \ -f webm_dash_manifest -i "input_video_360x640_750k.webm" \ -f webm_dash_manifest -i "audio.webm" \ -c copy \ -map 0 -map 1 -map 2 -map 3 \ -f webm_dash_manifest \ -adaptation_sets "id=0,streams=0,1,2 id=1,streams=3" \ "input_video_manifest.mpd" -f webm_dash_manifest -i "…": Specifies the inputs so that the ASH video player will switch between them dynamically based on network conditions. -map 0 -map 1 -map 2 -map 3: Includes all video (0, 1, 2) and audio (3) in the final manifest. -adaptation_sets: Groups streams into adaptation sets: id=0,streams=0,1,2: Groups the video renditions into a single adaptation set. id=1,streams=3: Assigns the audio track to a separate adaptation set. The resulting MPD file (input_video_manifest.mpd) describes the streams and enables adaptive bitrate streaming in MPEG-DASH. <?xml version="1.0" encoding="UTF-8"?> <MPD xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="urn:mpeg:DASH:schema:MPD:2011" xsi:schemaLocation="urn:mpeg:DASH:schema:MPD:2011" type="static" mediaPresentationDuration="PT81.166S" minBufferTime="PT1S" profiles="urn:mpeg:dash:profile:webm-on-demand:2012"> <Period id="0" start="PT0S" duration="PT81.166S"> <AdaptationSet id="0" mimeType="video/webm" codecs="vp9" lang="eng" bitstreamSwitching="true" subsegmentAlignment="false" subsegmentStartsWithSAP="1"> <Representation id="0" bandwidth="1647920" width="576" height="1024"> <BaseURL>input_video_576x1024_1500k.webm</BaseURL> <SegmentBase indexRange="16931581-16931910"> <Initialization range="0-645" /> </SegmentBase> </Representation> <Representation id="1" bandwidth="1126977" width="480" height="854"> <BaseURL>input_video_480x854_1000k.webm</BaseURL> <SegmentBase indexRange="11583599-11583986"> <Initialization range="0-645" /> </SegmentBase> </Representation> <Representation id="2" bandwidth="843267" width="360" height="640"> <BaseURL>input_video_360x640_750k.webm</BaseURL> <SegmentBase indexRange="8668326-8668713"> <Initialization range="0-645" /> </SegmentBase> </Representation> </AdaptationSet> <AdaptationSet id="1" mimeType="audio/webm" codecs="vorbis" lang="eng" audioSamplingRate="44100" bitstreamSwitching="true" subsegmentAlignment="true" subsegmentStartsWithSAP="1"> <Representation id="3" bandwidth="89219"> <BaseURL>audio.webm</BaseURL> <SegmentBase indexRange="921727-922055"> <Initialization range="0-4889" /> </SegmentBase> </Representation> </AdaptationSet> </Period> </MPD> After completing these steps, you’ll have: Three video renditions (576x1024, 480x854, 360x640), One audio track, and An MPD manifest file. input_video.mp4 audio.webm input_video_576x1024_1500k.webm input_video_480x854_1000k.webm input_video_360x640_750k.webm input_video_manifest.mpd The original video input_video.mp4 should also be kept to serve as a fallback video source later. Serve The Output Files These output files can now be uploaded to cloud storage (e.g., AWS S3 or Cloudflare R2) for playback. While they can be served directly from a local folder, I highly recommend storing them in cloud storage and leveraging a CDN to cache the assets for better performance. Both AWS and Cloudflare support HTTP range requests out of the box. Building The DASH-Compatible Video Player In React There’s nothing like a real-world example to help understand how everything works. There are different ways we can implement a DASH-compatible video player, but I’ll focus on an approach using React. First, install the Dash.js npm package by running: npm i dashjs Next, create a component called <DashVideoPlayer /> and initialize the Dash MediaPlayer instance by pointing it to the MPD file when the component mounts. The ref callback function runs upon the component mounting, and within the callback function, playerRef will refer to the actual Dash MediaPlayer instance and be bound with event listeners. We also include the original MP4 URL in the <source> element as a fallback if the browser doesn’t support MPEG-DASH. If you’re using Next.js app router, remember to add the ‘use client’ directive to enable client-side hydration, as the video player is only initialized on the client side. Here is the full example: import dashjs from 'dashjs' import { useCallback, useRef } from 'react' export const DashVideoPlayer = () => { const playerRef = useRef() const callbackRef = useCallback((node) => { if (node !== null) { playerRef.current = dashjs.MediaPlayer().create() playerRef.current.initialize(node, "https://example.com/uri/to/input_video_manifest.mpd", false) playerRef.current.on('canPlay', () => { // upon video is playable }) playerRef.current.on('error', (e) => { // handle error }) playerRef.current.on('playbackStarted', () => { // handle playback started }) playerRef.current.on('playbackPaused', () => { // handle playback paused }) playerRef.current.on('playbackWaiting', () => { // handle playback buffering }) } },[]) return ( <video ref={callbackRef} width={310} height={548} controls> <source src="https://example.com/uri/to/input_video.mp4" type="video/mp4" /> Your browser does not support the video tag. </video> ) } Result Observe the changes in the video file when the network connectivity is adjusted from Fast 4G to 3G using Chrome DevTools. It switches from 480p to 360p, showing how the experience is optimized for more or less available bandwidth. Conclusion That’s it! We just implemented a working DASH-compatible video player in React to establish a video with adaptive bitrate streaming. Again, the benefits of this are rooted in performance. When we adopt ABR streaming, we’re requesting the video in smaller chunks, allowing for more immediate playback than we’d get if we needed to fully download the video file first. And we’ve done it in a way that supports multiple versions of the same video, allowing us to serve the best format for the user’s device. References “Http Range Request And MP4 Video Play In Browser,” Zeng Xu Setting up adaptive streaming media sources (Mozilla Developer Network) DASH Adaptive Streaming for HTML video (Mozilla Developer Network)

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        Previewing Content Changes In Your Work With document.designMode

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          You probably already know that you can use developer tools in your browser to make on-the-spot changes to a webpage — simply click the node in the Inspector and make your edits. But have you tried `document.designMode`? Victor Ayomipo explains how it can be used to preview content changes and demonstrates several use cases where it comes in handy for everything from basic content editing to improving team collaboration.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          So, you just deployed a change to your website. Congrats! Everything went according to plan, but now that you look at your work in production, you start questioning your change. Perhaps that change was as simple as a new heading and doesn’t seem to fit the space. Maybe you added an image, but it just doesn’t feel right in that specific context. What do you do? Do you start deploying more changes? It’s not like you need to crack open Illustrator or Figma to mock up a small change like that, but previewing your changes before deploying them would still be helpful. Enter document.designMode. It’s not new. In fact, I just recently came across it for the first time and had one of those “Wait, this exists?” moments because it’s a tool we’ve had forever, even in Internet Explorer 6. But for some reason, I’m only now hearing about it, and it turns out that many of my colleagues are also hearing about it for the first time. What exactly is document.designMode? Perhaps a little video demonstration can help demonstrate how it allows you to make direct edits to a page. At its simplest, document.designMode makes webpages editable, similar to a text editor. I’d say it’s like having an edit mode for the web — one can click anywhere on a webpage to modify existing text, move stuff around, and even delete elements. It’s like having Apple’s “Distraction Control” feature at your beck and call. I think this is a useful tool for developers, designers, clients, and regular users alike. You might be wondering if this is just like contentEditable because, at a glance, they both look similar. But no, the two serve different purposes. contentEditable is more focused on making a specific element editable, while document.designMode makes the whole page editable. How To Enable document.designMode In DevTools Enabling document.designMode can be done in the browser’s developer tools: Right-click anywhere on a webpage and click Inspect. Click the Console tab. Type document.designMode = "on" and press Enter. To turn it off, refresh the page. That’s it. Another method is to create a bookmark that activates the mode when clicked: Create a new bookmark in your browser. You can name it whatever, e.g., “EDIT_MODE”. Input this code in the URL field: javascript:(function(){document.designMode = document.designMode === 'on' ? 'off' : 'on';})(); And now you have a switch that toggles document.designMode on and off. Use Cases There are many interesting, creative, and useful ways to use this tool. Basic Content Editing I dare say this is the core purpose of document.designMode, which is essentially editing any text element of a webpage for whatever reason. It could be the headings, paragraphs, or even bullet points. Whatever the case, your browser effectively becomes a “What You See Is What You Get” (WYSIWYG) editor, where you can make and preview changes on the spot. Landing Page A/B Testing Let’s say we have a product website with an existing copy, but then you check out your competitors, and their copy looks more appealing. Naturally, you’d want to test it out. Instead of editing on the back end or taking notes for later, you can use document.designMode to immediately see how that copy variation would fit into the landing page layout and then easily compare and contrast the two versions. This could also be useful for copywriters or solo developers. SEO Title And Meta Description Everyone wants their website to rank at the top of search results because that means more traffic. However, as broad as SEO is as a practice, the <title> tag and <meta> description is a website’s first impression in search results, both for visitors and search engines, as they can make or break the click-through rate. The question that arises is, how do you know if certain text gets cut off in search results? I think document.designMode can fix that before pushing it live. With this tool, I think it’d be a lot easier to see how different title lengths look when truncated, whether the keywords are instantly visible, and how compelling it’d be compared to other competitors on the same search result. Developer Workflows To be completely honest, developers probably won’t want to use document.designMode for actual development work. However, it can still be handy for breaking stuff on a website, moving elements around, repositioning images, deleting UI elements, and undoing what was deleted, all in real time. This could help if you’re skeptical about the position of an element or feel a button might do better at the top than at the bottom; document.designMode sure could help. It sure beats rearranging elements in the codebase just to determine if an element positioned differently would look good. But again, most of the time, we’re developing in a local environment where these things can be done just as effectively, so your mileage may vary as far as how useful you find document.designMode in your development work. Client And Team Collaboration It is a no-brainer that some clients almost always have last-minute change requests — stuff like “Can we remove this button?” or “Let’s edit the pricing features in the free tier.” To the client, these are just little tweaks, but to you, it could be a hassle to start up your development environment to make those changes. I believe document.designMode can assist in such cases by making those changes in seconds without touching production and sharing screenshots with the client. It could also become useful in team meetings when discussing UI changes. Seeing changes in real-time through screen sharing can help facilitate discussion and lead to quicker conclusions. Live DOM Tutorials For beginners learning web development, I feel like document.designMode can help provide a first look at how it feels to manipulate a webpage and immediately see the results — sort of like a pre-web development stage, even before touching a code editor. As learners experiment with moving things around, an instructor can explain how each change works and affects the flow of the page. Social Media Content Preview We can use the same idea to preview social media posts before publishing them! For instance, document.designMode can gauge the effectiveness of different call-to-action phrases or visualize how ad copy would look when users stumble upon it when scrolling through the platform. This would be effective on any social media platform. Memes I didn’t think it’d be fair not to add this. It might seem out of place, but let’s be frank: creating memes is probably one of the first things that comes to mind when anyone discovers document.designMode. You can create parody versions of social posts, tweak article headlines, change product prices, and manipulate YouTube views or Reddit comments, just to name a few of the ways you could meme things. Just remember: this shouldn’t be used to spread false information or cause actual harm. Please keep it respectful and ethical! Conclusion document.designMode = "on" is one of those delightful browser tricks that can be immediately useful when you discover it for the first time. It’s a raw and primitive tool, but you can’t deny its utility and purpose. So, give it a try, show it to your colleagues, or even edit this article. You never know when it might be exactly what you need. Further Reading “New Front-End Features For Designers In 2025,” Cosima Mielke “Useful DevTools Tips and Tricks,” Patrick Brosset “Useful CSS Tips And Techniques,” Cosima Mielke

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          Web Components Vs. Framework Components: What’s The Difference?

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            Some critics question the agnostic nature of Web Components, with some even arguing that they are not real components. Gabriel Shoyomboa explores this topic in-depth, comparing Web Components and framework components, highlighting their strengths and trade-offs, and evaluating their performance.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            It might surprise you that a distinction exists regarding the word “component,” especially in front-end development, where “component” is often used and associated with front-end frameworks and libraries. A component is a code that encapsulates a specific functionality and presentation. Components in front-end applications have a similar function: building reusable user interfaces. However, their implementations are different. Web — or “framework-agnostic” — components are standard web technologies for building reusable, self-sustained HTML elements. They consist of Custom Elements, Shadow DOM, and HTML template elements. On the other hand, framework components are reusable UIs explicitly tailored to the framework in which they are created. Unlike Web Components, which can be used in any framework, framework components are useless outside their frameworks. Some critics question the agnostic nature of Web Components and even go so far as to state that they are not real components because they do not conform to the agreed-upon nature of components. This article comprehensively compares web and framework components, examines the arguments regarding Web Components agnosticism, and considers the performance aspects of Web and framework components. What Makes A Component? Several criteria could be satisfied for a piece of code to be called a component, but only a few are essential: Reusability, Props and data handling, Encapsulation. Reusability is the primary purpose of a component, as it emphasizes the DRY (don’t repeat yourself) principle. A component should be designed to be reused in different parts of an application or across multiple applications. Also, a component should be able to accept data (in the form of props) from its parent components and optionally pass data back through callbacks or events. Components are regarded as self-contained units; therefore, they should encapsulate their logic, styles, and state. If there’s one thing we are certain of, framework components capture these criteria well, but what about their counterparts, Web Components? Understanding Web Components Web Components are a set of web APIs that allow developers to create custom, reusable HTML tags that serve a specific function. Based on existing web standards, they permit developers to extend HTML with new elements, custom behaviour, and encapsulated styling. Web Components are built based on three web specifications: Custom Elements, Shadow DOM, HTML templates. Each specification can exist independently, but when combined, they produce a web component. Custom Element The Custom Elements API makes provision for defining and using new types of DOM elements that can be reused. // Define a Custom Element class MyCustomElement extends HTMLElement { constructor() { super(); } connectedCallback() { this.innerHTML = ` <p>Hello from MyCustomElement!</p> `; } } // Register the Custom Element customElements.define('my-custom-element', MyCustomElement); Shadow DOM The Shadow DOM has been around since before the concept of web components. Browsers have used a nonstandard version for years for default browser controls that are not regular DOM nodes. It is a part of the DOM that is at least less reachable than typical light DOM elements as far as JavaScript and CSS go. These things are more encapsulated as standalone elements. // Create a Custom Element with Shadow DOM class MyShadowElement extends HTMLElement { constructor() { super(); this.attachShadow({ mode: 'open' }); } connectedCallback() { this.shadowRoot.innerHTML = ` <style> p { color: green; } </style> <p>Content in Shadow DOM</p> `; } } // Register the Custom Element customElements.define('my-shadow-element', MyShadowElement); HTML Templates HTML Templates API enables developers to write markup templates that are not loaded at the start of the app but can be called at runtime with JavaScript. HTML templates define the structure of Custom Elements in Web Components. // my-component.js export class MyComponent extends HTMLElement { constructor() { super(); this.attachShadow({ mode: 'open' }); } connectedCallback() { this.shadowRoot.innerHTML = ` <style> p { color: red; } </style> <p>Hello from ES Module!</p> `; } } // Register the Custom Element customElements.define('my-component', MyComponent); <!-- Import the ES Module --> <script type="module"> import { MyComponent } from './my-component.js'; </script> Web Components are often described as framework-agnostic because they rely on native browser APIs rather than being tied to any specific JavaScript framework or library. This means that Web Components can be used in any web application, regardless of whether it is built with React, Angular, Vue, or even vanilla JavaScript. Due to their supposed framework-agnostic nature, they can be created and integrated into any modern front-end framework and still function with little to no modifications. But are they actually framework-agnostic? The Reality Of Framework-Agnosticism In Web Components Framework-agnosticism is a term describing self-sufficient software — an element in this case — that can be integrated into any framework with minimal or no modifications and still operate efficiently, as expected. Web Components can be integrated into any framework, but not without changes that can range from minimal to complex, especially the styles and HTML arrangement. Another change Web Components might experience during integration includes additional configuration or polyfills for full browser support. This drawback is why some developers do not consider Web Components to be framework-agnostic. Notwithstanding, besides these configurations and edits, Web Components can easily fit into any front-end framework, including but not limited to React, Angular, and Vue. Framework Components: Strengths And Limitations Framework components are framework-specific reusable bits of code. They are regarded as the building blocks of the framework on which they are built and possess several benefits over Web Components, including the following: An established ecosystem and community support, Developer-friendly integrations and tools, Comprehensive documentation and resources, Core functionality, Tested code, Fast development, Cross-browser support, and Performance optimizations. Examples of commonly employed front-end framework elements include React components, Vue components, and Angular directives. React supports a virtual DOM and one-way data binding, which allows for efficient updates and a component-based model. Vue is a lightweight framework with a flexible and easy-to-learn component system. Angular, unlike React, offers a two-way data binding component model with a TypeScript focus. Other front-end framework components include Svelte components, SolidJS components, and more. Framework layer components are designed to operate under a specific JavaScript framework such as React, Vue, or Angular and, therefore, reside almost on top of the framework architecture, APIs, and conventions. For instance, React components use JSX and state management by React, while Angular components leverage Angular template syntax and dependency injection. As far as benefits, it has excellent developer experience performance, but as far as drawbacks are concerned, they are not flexible or reusable outside the framework. In addition, a state known as vendor lock-in is created when developers become so reliant on some framework or library that they are unable to switch to another. This is possible with framework components because they are developed to be operational only in the framework environment. Comparative Analysis Framework and Web Components have their respective strengths and weaknesses and are appropriate to different scenarios. However, a comparative analysis based on several criteria can help deduce the distinction between both. Encapsulation And Styling: Scoped Vs. Isolated Encapsulation is a trademark of components, but Web Components and framework components handle it differently. Web Components provide isolated encapsulation with the Shadow DOM, which creates a separate DOM tree that shields a component’s styles and structure from external manipulation. That ensures a Web Component will look and behave the same wherever it is used. However, this isolation can make it difficult for developers who need to customize styles, as external CSS cannot cross the Shadow DOM without explicit workarounds (e.g., CSS custom properties). Scoped styling is used by most frameworks, which limit CSS to a component using class names, CSS-in-JS, or module systems. While this dissuades styles from leaking outwards, it does not entirely prevent external styles from leaking in, with the possibility of conflicts. Libraries like Vue and Svelte support scoped CSS by default, while React often falls back to libraries like styled-components. Reusability And Interoperability Web Components are better for reusable components that are useful for multiple frameworks or vanilla JavaScript applications. In addition, they are useful when the encapsulation and isolation of styles and behavior must be strict or when you want to leverage native browser APIs without too much reliance on other libraries. Framework components are, however, helpful when you need to leverage some of the features and optimisations provided by the framework (e.g., React reconciliation algorithm, Angular change detection) or take advantage of the mature ecosystem and tools available. You can also use framework components if your team is already familiar with the framework and conventions since it will make your development process easier. Performance Considerations Another critical factor in determining web vs. framework components is performance. While both can be extremely performant, there are instances where one will be quicker than the other. For Web Components, implementation in the native browser can lead to optimised rendering and reduced overhead, but older browsers may require polyfills, which add to the initial load. While React and Angular provide specific optimisations (e.g., virtual DOM, change detection) that will make performance improvements on high-flow, dynamic applications, they add overhead due to the framework runtime and additional libraries. Developer Experience Developer experience is another fundamental consideration regarding Web Components versus framework components. Ease of use and learning curve can play a large role in determining development time and manageability. Availability of tooling and community support can influence developer experience, too. Web Components use native browser APIs and, therefore, are comfortable to developers who know HTML, CSS, and JavaScript but have a steeper learning curve due to additional concepts like the Shadow DOM, custom elements, and templates that have a learning curve attached to them. Also, Web Components have a smaller community and less community documentation compared to famous frameworks like React, Angular, and Vue. Side-by-Side Comparison Web Components Benefits Framework Components Benefits Native browser support can lead to efficient rendering and reduced overhead. Frameworks like React and Angular provide specific optimizations (e.g., virtual DOM, change detection) that can improve performance for large, dynamic applications. Smaller bundle sizes and native browser support can lead to faster load times. Frameworks often provide tools for optimizing bundle sizes and lazy loading components. Leverage native browser APIs, making them accessible to developers familiar with HTML, CSS, and JavaScript. Extensive documentation, which makes it easier for developers to get started. Native browser support means fewer dependencies and the potential for better performance. Rich ecosystem with extensive tooling, libraries, and community support. Web Components Drawbacks Framework Components Drawbacks Older browsers may require polyfills, which can add to the initial load time. Framework-specific components can add overhead due to the framework’s runtime and additional libraries. Steeper learning curve due to additional concepts like Shadow DOM and Custom Elements. Requires familiarity with the framework’s conventions and APIs. Smaller ecosystem and fewer community resources compared to popular frameworks. Tied to the framework, making it harder to switch to a different framework. To summarize, the choice between Web Components and framework components depends on the specific need of your project or team, which can include cross-framework reusability, performance, and developer experience. Conclusion Web Components are the new standard for agnostic, interoperable, and reusable components. Although they need further upgrades and modifications in terms of their base technologies to meet framework components standards, they are entitled to the title “components.” Through a detailed comparative analysis, we’ve explored the strengths and weaknesses of Web Components and framework components, gaining insight into their differences. Along the way, we also uncovered useful workarounds for integrating web components into front-end frameworks for those interested in that approach. References What are Web Components? (WebComponents.org) Web Components Specifications (WebComponents.org) Web Components (MDN) Using Shadow DOM (MDN) “Web Components Aren’t Components”, Keith J. Grant

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            How To Prevent WordPress SQL Injection Attacks

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              Have you thought about the security risks WordPress websites face? Anders Johansson explores why they are frequent hacker targets and shares how WordPress SQL injection attacks work and how to remove and prevent them.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              Did you know that your WordPress site could be a target for hackers right now? That’s right! Today, WordPress powers over 43% of all websites on the internet. That kind of public news makes WordPress sites a big target for hackers. One of the most harmful ways they attack is through an SQL injection. A SQL injection may break your website, steal data, and destroy your content. More than that, they can lock you out of your website! Sounds scary, right? But don’t worry, you can protect your site. That is what this article is about. What Is SQL? SQL stands for Structured Query Language. It is a way to talk to databases, which store and organize a lot of data, such as user details, posts, or comments on a website. SQL helps us ask the database for information or give it new data to store. When writing an SQL query, you ask the database a question or give it a task. For example, if you want to see all users on your site, an SQL query can retrieve that list. SQL is powerful and vital since all WordPress sites use databases to store content. What Is An SQL Injection Attack? WordPress SQL injection attacks try to gain access to your site’s database. An SQL injection (SQLi) lets hackers exploit a vulnerable SQL query to run a query they made. The attack occurs when a hacker tricks a database into running harmful SQL commands. Hackers can send these commands via input fields on your site, such as those in login forms or search bars. If the website does not check input carefully, a command can grant access to the database. Imagine a hacker typing an SQL command instead of typing a username. It may fool the database and show private data such as passwords and emails. The attacker could use it to change or delete database data. Your database holds all your user-generated data and content. It stores pages, posts, links, comments, and users. For the “bad” guys, it is a goldmine of valuable data. SQL injections are dangerous as they let hackers steal data or take control of a website. A WordPress firewall prevents SQL injection attacks. Those attacks can compromise and hack sites very fast. SQL Injections: Three Main Types There are three main kinds of SQL injection attacks. Every type works in various ways, but they all try to fool the database. We’re going to look at every single type. In-Band SQLi This is perhaps the most common type of attack. A hacker sends the command and gets the results using the same communication method. It is to make a request and get the answer right away. There are two types of In-band SQLi injection attacks: Error-based SQLi, Union-based SQLi. With error-based SQLi, the hacker causes the database to give an error message. This message may reveal crucial data, such as database structure and settings. What about union-based SQLi attacks? The hacker uses the SQL UNION statement to combine their request with a standard query. It can give them access to other data stored in the database. Inferential SQLi With inferential SQLi, the hacker will not see the results at once. Instead, they ask for database queries that give “yes” and “no” answers. Hackers can reveal the database structure or data by how the site responds. They do that in two common ways: Boolean-based SQLi, Time-based SQLi. Through Boolean-based SQLi, the hacker sends queries that can only be “true” or “false.” For example, is this user ID more than 100? This allows hackers to gather more data about the site based on how it reacts. In time-based SQLi, the hacker asks a query that makes the database take longer to reply if the answer is “yes.” They can figure out what they need to know due to the delay. Out-of-band SQLi Out-of-band SQLi is a less common but equally dangerous type of attack. Hackers use various ways to get results. Usually, they connect the database to a server they control. The hacker does not see the results all at once. However, they can get the data sent somewhere else via email or a network connection. This method applies when the site blocks ordinary SQL injection methods. Why Preventing SQL Injection Is Crucial SQL injections are a giant risk for websites. They can lead to various harms — stolen data, website damage, legal issues, loss of trust, and more. Hackers can steal data like usernames, passwords, and emails. They may cause damage by deleting and changing your data. Besides, it messes up your site structure, making it unusable. Is your user data stolen? You might face legal troubles if your site treats sensitive data. People may lose trust in you if they see that your site gets hacked. As a result, the reputation of your site can suffer. Thus, it is so vital to prevent SQL injections before they occur. 11 Ways To Prevent WordPress SQL Injection Attacks OK, so we know what SQL is and that WordPress relies on it. We also know that attackers take advantage of SQL vulnerabilities. I’ve collected 11 tips for keeping your WordPress site free of SQL injections. The tips limit your vulnerability and secure your site from SQL injection attacks. 1. Validate User Input SQL injection attacks usually occur via forms or input fields on your site. It could be inside a login form, a search box, a contact form, or a comment section. Does a hacker enter bad SQL commands into one of these fields? They may fool your site, giving them access to your database by running those commands. Hence, always sanitize and validate all input data on your site. Users should not be able to submit data if it does not follow a specific format. The easiest way to avoid this is to use a plugin like Formidable Forms, an advanced builder for adding forms. That said, WordPress has many built-in functions to sanitize and validate input on your own. It includes sanitize_text_field(), sanitize_email(), and sanitize_url(). The validation cleans up user inputs before they get sent to your database. These functions strip out unwanted characters and ensure the data is safe to store. 2. Avoid Dynamic SQL Dynamic SQL allows you to create SQL statements on the fly at runtime. How does dynamic SQL work compared to static SQL? You can create flexible and general SQL queries adjusted to various conditions. As a result, dynamic SQL is typically slower than static SQL, as it demands runtime parsing. Dynamic SQL can be more vulnerable to SQL injection attacks. It occurs when the bad guy alters a query by injecting evil SQL code. The database may respond and run this harmful code. As a result, the attacker can access data, corrupt it, or even hack your entire database. How do you keep your WordPress site safe? Use prepared statements, stored procedures or parameterized queries. 3. Regularly Update WordPress Themes And Plugins Keeping WordPress and all plugins updated is the first step in keeping your site safe. Hackers often look for old software versions with known security issues. There are regular security updates for WordPress, themes, and plugins. They fix security issues. You leave your site open to attacks as you ignore these updates. To stay safe, set up automatic updates for minor WordPress versions. Check for theme and plugin updates often. Only use trusted plugins from the official WordPress source or well-known developers. By updating often, you close many ways hackers could attack. 4. Add A WordPress Firewall A firewall is one of the best ways to keep your WordPress website safe. It is a shield for your WordPress site and a security guard that checks all incoming traffic. The firewall decides who can enter your site and who gets blocked. There are five main types of WordPress firewalls: Plugin-based firewalls, Web application firewalls, Cloud-based firewalls, DNS-level firewalls, Application-level firewalls. Plugin-based firewalls you install on your WordPress site. They work from within your website to block the bad traffic. Web application firewalls filter, check and block the traffic to and from a web service. They detect and defend against risky security flaws that are most common in web traffic. Cloud-based firewalls work from outside your site. They block the bad traffic before it even reaches your site. DNS-level firewalls send your site traffic via their cloud proxy servers, only letting them direct real traffic to your web server. Finally, application-level firewalls check the traffic as it reaches your server. That means before loading most of the WordPress scripts. Stable security plugins like Sucuri and Wordfence can also act as firewalls. 5. Hide Your WordPress Version Older WordPress versions display the WordPress version in the admin footer. It’s not always a bad thing to show your version of WordPress. But revealing it does provide virtual ammo to hackers. They want to exploit vulnerabilities in outdated WordPress versions. Are you using an older WordPress version? You can still hide your WordPress version: With a security plugin such as Sucuri or Wordfence to clear the version number or By adding a little bit of code to your functions.php file. function hide_wordpress_version() { return ''; } add_filter('the_generator', 'hide_wordpress_version'); This code stops your WordPress version number from showing in the theme’s header.php file and RSS feeds. It adds a small but helpful layer of security. Thus, it becomes more difficult for hackers to detect. 6. Make Custom Database Error Notices Bad guys can see how your database is set up via error notices. Ensure creating a custom database error notice that users see to stop it. Hackers will find it harder to detect weak spots in your site when you hide error details. The site will stay much safer when you show less data on the front end. To do that, copy and paste the code into a new db-error.php file. Jeff Starr has a classic article on the topic from 2009 with an example: <?php // Custom WordPress Database Error Page header('HTTP/1.1 503 Service Temporarily Unavailable'); header('Status: 503 Service Temporarily Unavailable'); header('Retry-After: 600'); // 1 hour = 3600 seconds // If you want to send an email to yourself upon an error // mail("your@email.com", "Database Error", "There is a problem with the database!", "From: Db Error Watching"); ?> <!DOCTYPE HTML> <html> <head> <title>Database Error</title> <style> body { padding: 50px; background: #04A9EA; color: #fff; font-size: 30px; } .box { display: flex; align-items: center; justify-content: center; } </style> </head> <body> <div class="box"> <h1>Something went wrong</h1> </div> </body> </html> Now save the file in the root of your /wp-content/ folder for it to take effect. 7. Set Access And Permission Limits For User Roles Assign only the permissions that each role demands to do its tasks. For example, Editors may not need access to the WordPress database or plugin settings. Improve site security by giving only the admin role full dashboard access. Limiting access to features for fewer roles reduces the odds of an SQL injection attack. 8. Enable Two-factor Authentication A great way to protect your WordPress site is to apply two-factor authentication (2FA). Why? Since it adds an extra layer of security to your login page. Even if a hacker cracks your password, they still won’t be able to log in without getting access to the 2FA code. Setting up 2FA on WordPress goes like this: Install a two-factor authentication plugin. Google Authenticator by miniOrange, Two-Factor, and WP 2FA by Melapress are good options. Pick your authentication method. The plugins often have three choices: SMS codes, authentication apps, or security keys. Link your account. Are you using Google Authenticator? Start and scan the QR code inside the plugin settings to connect it. If you use SMS, enter your phone number and get codes via text. Test it. Log out of WordPress and try to log in again. First, enter your username and password as always. Second, you complete the 2FA step and type in the code you receive via SMS or email. Enable backup codes (optional). Some plugins let you generate backup codes. Save these in a safe spot in case you lose access to your phone or email. 9. Delete All Unneeded Database Functions Assure erasing tables you no longer use and delete junk or unapproved comments. Your database will be more resistant to hackers who try to exploit sensitive data. 10. Monitor Your Site For Unusual Activity Watch for unusual activity on your site. You can check for actions like many failed login attempts or strange traffic spikes. Security plugins such as Wordfence or Sucuri alert you when something seems odd. That helps to catch issues before they get worse. 11. Backup Your Site Regularly Running regular backups is crucial. With a backup, you can quickly restore your site to its original state if it gets hacked. You want to do this anytime you execute a significant update on your site. Also, it regards updating your theme and plugins. Begin to create a plan for your backups so it suits your needs. For example, if you publish new content every day, then it may be a good idea to back up your database and files daily. Many security plugins offer automated backups. Of course, you can also use backup plugins like UpdraftPlus or Solid Security. You should store backup copies in various locations, such as Dropbox and Google Drive. It will give you peace of mind. How To Remove SQL Injection From Your Site Let’s say you are already under attack and are dealing with an active SQL injection on your site. It’s not like any of the preventative measures we’ve covered will help all that much. Here’s what you can do to fight back and defend your site: Check your database for changes. Look for strange entries in user accounts, content, or plugin settings. Erase evil code. Scan your site with a security plugin like Wordfence or Sucuri to find and erase harmful code. Restore a clean backup. Is the damage vast? Restoring your site from an existing backup could be the best option. Change all passwords. Alter your passwords for the WordPress admin, the database, and the hosting account. Harden your site security. After cleaning your site, take the 11 steps we covered earlier to prevent future attacks. Conclusion Hackers love weak sites. They look for easy ways to break in, steal data, and cause harm. One of the tricks they often use is SQL injection. If they find a way in, they can steal private data, alter your content, or even take over your site. That’s bad news both for you and your visitors. But here is the good news: You can stop them! It is possible to block these attacks before they happen by taking the correct steps. And you don’t need to be a tech freak. Many people ignore website security until it’s too late. They think, “Why would a hacker target my site?” But hackers don’t attack only big sites. They attack any site with weak security. So, even small blogs and new websites are in danger. Once a hacker gets in, this person can cause you lots of damage. Fixing a hacked site takes time, effort, and money. But stopping an attack before it happens? That’s much easier. Hackers don’t sit and wait, so why should you? Thousands of sites get attacked daily, so don’t let yours be the next one. Update your site, add a firewall, enable 2FA, and check your security settings. These small steps can help prevent giant issues in the future. Your site needs protection against the bad guys. You have worked hard to build it. Never neglect to update and protect it. After that, your site will be safer and sounder.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              How To Build Confidence In Your UX Work

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                UX initiatives are often seen as a disruption rather than a means to solving existing problems in an organization. In this post, we’ll explore how you can build trust for your UX work, gain support, and make a noticeable impact. Part of [Measure UX and Design Impact](https://measure-ux.com/) by yours truly.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                When I start any UX project, typically, there is very little confidence in the successful outcome of my UX initiatives. In fact, there is quite a lot of reluctance and hesitation, especially from teams that have been burnt by empty promises and poor delivery in the past. Good UX has a huge impact on business. But often, we need to build up confidence in our upcoming UX projects. For me, an effective way to do that is to address critical bottlenecks and uncover hidden deficiencies — the ones that affect the people I’ll be working with. Let’s take a closer look at what this can look like. This article is part of our ongoing series on UX. You can find more details on design patterns and UX strategy in Smart Interface Design Patterns 🍣 — with live UX training coming up soon. Free preview. UX Doesn’t Disrupt, It Solves Problems Bottlenecks are usually the most disruptive part of any company. Almost every team, every unit, and every department has one. It’s often well-known by employees as they complain about it, but it rarely finds its way to senior management as they are detached from daily operations. The bottleneck can be the only senior developer on the team, a broken legacy tool, or a confusing flow that throws errors left and right — there’s always a bottleneck, and it’s usually the reason for long waiting times, delayed delivery, and cutting corners in all the wrong places. We might not be able to fix the bottleneck. But for a smooth flow of work, we need to ensure that non-constraint resources don’t produce more than the constraint can handle. All processes and initiatives must be aligned to support and maximize the efficiency of the constraint. So before doing any UX work, look out for things that slow down the organization. Show that it’s not UX work that disrupts work, but it’s internal disruptions that UX can help with. And once you’ve delivered even a tiny bit of value, you might be surprised how quickly people will want to see more of what you have in store for them. The Work Is Never Just “The Work” Meetings, reviews, experimentation, pitching, deployment, support, updates, fixes — unplanned work blocks other work from being completed. Exposing the root causes of unplanned work and finding critical bottlenecks that slow down delivery is not only the first step we need to take when we want to improve existing workflows, but it is also a good starting point for showing the value of UX. To learn more about the points that create friction in people’s day-to-day work, set up 1:1s with the team and ask them what slows them down. Find a problem that affects everyone. Perhaps too much work in progress results in late delivery and low quality? Or lengthy meetings stealing precious time? One frequently overlooked detail is that we can’t manage work that is invisible. That’s why it is so important that we visualize the work first. Once we know the bottleneck, we can suggest ways to improve it. It could be to introduce 20% idle times if the workload is too high, for example, or to make meetings slightly shorter to make room for other work. The Theory Of Constraints The idea that the work is never just “the work” is deeply connected to the Theory of Constraints discovered by Dr. Eliyahu M. Goldratt. It showed that any improvements made anywhere beside the bottleneck are an illusion. Any improvement after the bottleneck is useless because it will always remain starved, waiting for work from the bottleneck. And any improvements made before the bottleneck result in more work piling up at the bottleneck. Wait Time = Busy ÷ Idle To improve flow, sometimes we need to freeze the work and bring focus to one single project. Just as important as throttling the release of work is managing the handoffs. The wait time for a given resource is the percentage of time that the resource is busy divided by the percentage of time it’s idle. If a resource is 50% utilized, the wait time is 50/50, or 1 unit. If the resource is 90% utilized, the wait time is 90/10, or 9 times longer. And if it’s 99% of time utilized, it’s 99/1, so 99 times longer than if that resource is 50% utilized. The critical part is to make wait times visible so you know when your work spends days sitting in someone’s queue. The exact times don’t matter, but if a resource is busy 99% of the time, the wait time will explode. Avoid 100% Occupation Our goal is to maximize flow: that means exploiting the constraint but creating idle times for non-constraint to optimize system performance. One surprising finding for me was that any attempt to maximize the utilization of all resources — 100% occupation across all departments — can actually be counterproductive. As Goldratt noted, “An hour lost at a bottleneck is an hour out of the entire system. An hour saved at a non-bottleneck is worthless.” Recommended Read: “The Phoenix Project” I can only wholeheartedly recommend The Phoenix Project, an absolutely incredible book that goes into all the fine details of the Theory of Constraints described above. It’s not a design book but a great book for designers who want to be more strategic about their work. It’s a delightful and very real read about the struggles of shipping (albeit on a more technical side). Wrapping Up People don’t like sudden changes and uncertainty, and UX work often disrupts their usual ways of working. Unsurprisingly, most people tend to block it by default. So before we introduce big changes, we need to get their support for our UX initiatives. We need to build confidence and show them the value that UX work can have — for their day-to-day work. To achieve that, we can work together with them. Listening to the pain points they encounter in their workflows, to the things that slow them down. Once we’ve uncovered internal disruptions, we can tackle these critical bottlenecks and suggest steps to make existing workflows more efficient. That’s the foundation to gaining their trust and showing them that UX work doesn’t disrupt but that it’s here to solve problems. New: How To Measure UX And Design Impact Meet Measure UX & Design Impact (8h), a practical guide for designers and UX leads to measure and show your UX impact on business. Watch the free preview or jump to the details. Video + UX Training Video only Video + UX Training $ 495.00 $ 799.00 Get Video + UX Training 25 video lessons (8h) + Live UX Training. 100 days money-back-guarantee. Video only $ 250.00$ 395.00 Get the video course 25 video lessons (8h). Updated yearly. Also available as a UX Bundle with 2 video courses.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                How To Fix Largest Contentful Paint Issues With Subpart Analysis

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  Struggling with slow Largest Contentful Paint (LCP)? Newly introduced by Google, LCP subparts help you pinpoint where page load delays come from. Now, in the Chrome UX Report, this data provides real visitor insights to speed up your site and boost rankings. Matt Zeunert unpacks what LCP subparts are, what they mean for your website speed, and how you can measure them.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  This article is a sponsored by DebugBear The Largest Contentful Paint (LCP) in Core Web Vitals measures how quickly a website loads from a visitor’s perspective. It looks at how long after opening a page the largest content element becomes visible. If your website is loading slowly, that’s bad for user experience and can also cause your site to rank lower in Google. When trying to fix LCP issues, it’s not always clear what to focus on. Is the server too slow? Are images too big? Is the content not being displayed? Google has been working to address that recently by introducing LCP subparts, which tell you where page load delays are coming from. They’ve also added this data to the Chrome UX Report, allowing you to see what causes delays for real visitors on your website! Let’s take a look at what the LCP subparts are, what they mean for your website speed, and how you can measure them. The Four LCP Subparts LCP subparts split the Largest Contentful Paint metric into four different components: Time to First Byte (TTFB): How quickly the server responds to the document request. Resource Load Delay: Time spent before the LCP image starts to download. Resource Load Time: Time spent downloading the LCP image. Element Render Delay: Time before the LCP element is displayed. The resource timings only apply if the largest page element is an image or background image. For text elements, the Load Delay and Load Time components are always zero. How To Measure LCP Subparts One way to measure how much each component contributes to the LCP score on your website is to use DebugBear’s website speed test. Expand the Largest Contentful Paint metric to see subparts and other details related to your LCP score. Here, we can see that TTFB and image Load Duration together account for 78% of the overall LCP score. That tells us that these two components are the most impactful places to start optimizing. What’s happening during each of these stages? A network request waterfall can help us understand what resources are loading through each stage. The LCP Image Discovery view filters the waterfall visualization to just the resources that are relevant to displaying the Largest Contentful Paint image. In this case, each of the first three stages contains one request, and the final stage finishes quickly with no new resources loaded. But that depends on your specific website and won’t always be the case. Time To First Byte The first step to display the largest page element is fetching the document HTML. We recently published an article about how to improve the TTFB metric. In this example, we can see that creating the server connection doesn’t take all that long. Most of the time is spent waiting for the server to generate the page HTML. So, to improve the TTFB, we need to speed up that process or cache the HTML so we can skip the HTML generation entirely. Resource Load Delay The “resource” we want to load is the LCP image. Ideally, we just have an <img> tag near the top of the HTML, and the browser finds it right away and starts loading it. But sometimes, we get a Load Delay, as is the case here. Instead of loading the image directly, the page uses lazysize.js, an image lazy loading library that only loads the LCP image once it has detected that it will appear in the viewport. Part of the Load Delay is caused by having to download that JavaScript library. But the browser also needs to complete the page layout and start rendering content before the library will know that the image is in the viewport. After finishing the request, there’s a CPU task (in orange) that leads up to the First Contentful Paint milestone, when the page starts rendering. Only then does the library trigger the LCP image request. How do we optimize this? First of all, instead of using a lazy loading library, you can use the native loading="lazy" image attribute. That way, loading images no longer depends on first loading JavaScript code. But more specifically, the LCP image should not be lazily loaded. That way, the browser can start loading it as soon as the HTML code is ready. According to Google, you should aim to eliminate resource load delay entirely. Resources Load Duration The Load Duration subpart is probably the most straightforward: you need to download the LCP image before you can display it! In this example, the image is loaded from the same domain as the HTML. That’s good because the browser doesn’t have to connect to a new server. Other techniques you can use to reduce load delay: Use a modern image format that provides better compression. Load images at a size that matches the size they are displayed at. Deprioritize other resources that might compete with the LCP image. Element Render Delay The fourth and final LCP component, Render Delay, is often the most confusing. The resource has loaded, but for some reason, the browser isn’t ready to show it to the user yet! Luckily, in the example we’ve been looking at so far, the LCP image appears quickly after it’s been loaded. One common reason for render delay is that the LCP element is not an image. In that case, the render delay is caused by render-blocking scripts and stylesheets. The text can only appear after these have loaded and the browser has completed the rendering process. Another reason you might see render delay is when the website preloads the LCP image. Preloading is a good idea, as it practically eliminates any load delay and ensures the image is loaded early. However, if the image finishes downloading before the page is ready to render, you’ll see an increase in render delay on the page. And that’s fine! You’ve improved your website speed overall, but after optimizing your image, you’ve uncovered a new bottleneck to focus on. LCP Subparts In Real User CrUX Data Looking at the Largest Contentful Paint subparts in lab-based tests can provide a lot of insight into where you can optimize. But all too often, the LCP in the lab doesn’t match what’s happening for real users! That’s why, in February 2025, Google started including subpart data in the CrUX data report. It’s not (yet?) included in PageSpeed Insights, but you can see those metrics in DebugBear’s “Web Vitals” tab. One super useful bit of info here is the LCP resource type: it tells you how many visitors saw the LCP element as a text element or an image. Even for the same page, different visitors will see slightly different content. For example, different elements are visible based on the device size, or some visitors will see a cookie banner while others see the actual page content. To make the data easier to interpret, Google only reports subpart data for images. If the LCP element is usually text on the page, then the subparts info won’t be very helpful, as it won’t apply to most of your visitors. But breaking down text LCP is relatively easy: everything that’s not part of the TTFB score is render-delayed. Track Subparts On Your Website With Real User Monitoring Lab data doesn’t always match what real users experience. CrUX data is superficial, only reported for high-traffic pages, and takes at least 4 weeks to fully update after a change has been rolled out. That’s why a real-user monitoring tool like DebugBear comes in handy when fixing your LCP scores. You can track scores across all pages on your website over time and get dedicated dashboards for each LCP subpart. You can also review specific visitor experiences, see what the LCP image was for them, inspect a request waterfall, and check LCP subpart timings. Sign up for a free trial. Conclusion Having more granular metric data available for the Largest Contentful Paint gives web developers a big leg up when making their website faster. Including subparts in CrUX provides new insight into how real visitors experience your website and can tell if the optimizations you’re considering would really be impactful.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  The Case For Minimal WordPress Setups: A Contrarian View On Theme Frameworks

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    Modern frameworks are supposed to help speed up development while providing modern tools and a developer-friendly workflow. In reality, Kevin Leary has found that they cause far more problems than they solve. This ultimately leads to the big question: why are modern theme frameworks so popular, and do they really benefit developers in the long run?

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    When it comes to custom WordPress development, theme frameworks like Sage and Genesis have become a go-to solution, particularly for many agencies that rely on frameworks as an efficient starting point for client projects. They promise modern standards, streamlined workflows, and maintainable codebases. At face value, these frameworks seem to be the answer to building high-end, bespoke WordPress websites. However, my years of inheriting these builds as a freelance developer tell a different story — one rooted in the reality of long-term maintenance, scalability, and developer onboarding. As someone who specializes in working with professional websites, I’m frequently handed projects originally built by agencies using these frameworks. This experience has given me a unique perspective on the real-world implications of these tools over time. While they may look great in an initial pitch, their complexities often create friction for future developers, maintenance teams, and even the businesses they serve. This is not to say frameworks like Sage or Genesis are without merit, but they are far from the universal “best practice” they’re often touted to be. Below, I’ll share the lessons I’ve learned from inheriting and working with these setups, the challenges I’ve faced, and why I believe a minimal WordPress approach often provides a better path forward. Why Agencies Use Frameworks Frameworks are designed to make WordPress development faster, cleaner, and optimized for current best practices. Agencies are drawn to these tools for several reasons: Current code standards Frameworks like Sage adopt PSR-2 standards, composer-based dependency management, and MVC-like abstractions. Reusable components Sage’s Blade templating encourages modularity, while Genesis relies on hooks for extensive customization. Streamlined design tools Integration with Tailwind CSS, SCSS, and Webpack (or newer tools like Bud) allows rapid prototyping. Optimized performance Frameworks are typically designed with lightweight, bloat-free themes in mind. Team productivity By creating a standardized approach, these frameworks promise efficiency for larger teams with multiple contributors. On paper, these benefits make frameworks an enticing choice for agencies. They simplify the initial build process and cater to developers accustomed to working with modern PHP practices and JavaScript-driven tooling. But whenever I inherit these projects years later, the cracks in the foundation begin to show. The Reality of Maintaining Framework-Based Builds While frameworks have their strengths, my firsthand experience reveals recurring issues that arise when it’s time to maintain or extend these builds. These challenges aren’t theoretical — they are issues I’ve encountered repeatedly when stepping into an existing framework-based site. 1. Abstraction Creates Friction One of the selling points of frameworks is their use of abstractions, such as Blade templating and controller-to-view separation. While these patterns make sense in theory, they often lead to unnecessary complexity in practice. For instance, Blade templates abstract PHP logic from WordPress’s traditional theme hierarchy. This means errors like syntax issues don’t provide clear stack traces pointing to the actual view file — rather, they reference compiled templates. Debugging becomes a scavenger hunt, especially for developers unfamiliar with Sage’s structure. One example is a popular news outlet with millions of monthly visitors. When I first inherited their Sage-based theme, I had to bypass their Lando/Docker environment to use my own minimal Nginx localhost setup. The theme was incompatible with standard WordPress workflows, and I had to modify build scripts to support a traditional installation. Once I resolved the environment issues, I realized their build process was incredibly slow, with hot module replacement only partially functional (Blade template changes wouldn’t reload). Each save took 4–5 seconds to compile. Faced with a decision to either upgrade to Sage 10 or rebuild the critical aspects, I opted for the latter. We drastically improved performance by replacing the Sage build with a simple Laravel Mix process. The new build process was reduced from thousands of lines to 80, significantly improving developer workflow. Any new developer could now understand the setup quickly, and future debugging would be far simpler. 2. Inflexible Patterns While Sage encourages “best practices,” these patterns can feel rigid and over-engineered for simple tasks. Customizing basic WordPress features — like adding a navigation menu or tweaking a post query — requires following the framework’s prescribed patterns. This introduces a learning curve for developers who aren’t deeply familiar with Sage, and slows down progress for minor adjustments. Traditional WordPress theme structures, by contrast, are intuitive and widely understood. Any WordPress developer, regardless of background, can jump into a classic theme and immediately know where to look for templates, logic, and customizations. Sage’s abstraction layers, while well-meaning, limit accessibility to a smaller, more niche group of developers. 3. Hosting Compatibility Issues When working with Sage, issues with hosting environments are inevitable. For example, Sage’s use of Laravel Blade compiles templates into cached PHP files, often stored in directories like /wp-content/cache. Strict file system rules on managed hosting platforms, like WP Engine, can block these writes, leading to white screens or broken templates after deployment. This was precisely the issue I faced with a custom agency-built theme using the Sage theme on WPEngine." Every Git deployment resulted in a white screen of death due to PHP errors caused by Blade templates failing to save in the intended cache directory. The solution, recommended by WP Engine support, was to use the system’s /tmp directory. While this workaround prevented deployment errors, it undermined the purpose of cached templates, as temporary files are cleared by PHP’s garbage collection. Debugging and implementing this solution consumed significant time — time that could have been avoided had the theme been designed with hosting compatibility in mind. 4. Breaking Changes And Upgrade Woes Upgrading from Sage 9 to Sage 10 — or even from older versions of Roots — often feels like a complete rebuild. These breaking changes create friction for businesses that want long-term stability. Clients, understandably, are unwilling to pay for what amounts to refactoring without a visible return on investment. As a result, these sites stagnate, locked into outdated versions of the framework, creating problems with dependency management (e.g., Composer packages, Node.js versions) and documentation mismatches. One agency subcontract I worked on recently gave me insight into Sage 10’s latest approach. Even on small microsites with minimal custom logic, I found the Bud-based build system sluggish, with watch processes taking over three seconds to reload. For developers accustomed to faster workflows, this is unacceptable. Additionally, Sage 10 introduced new patterns and directives that departed significantly from Sage 9, adding a fresh learning curve. While I understand the appeal of mirroring Laravel’s structure, I couldn’t shake the feeling that this complexity was unnecessary for WordPress. By sticking to simpler approaches, the footprint could be smaller, the performance faster, and the maintenance much easier. The Cost Of Over-Engineering The issues above boil down to one central theme: over-engineering. Frameworks like Sage introduce complexity that, while beneficial in theory, often outweighs the practical benefits for most WordPress projects. When you factor in real-world constraints — like tight budgets, frequent developer turnover, and the need for intuitive codebases — the case for a minimal approach becomes clear. Minimal WordPress setups embrace simplicity: No abstraction for abstraction’s sake Traditional WordPress theme hierarchy is straightforward, predictable, and accessible to a broad developer audience. Reduced tooling overhead Avoiding reliance on tools like Webpack or Blade removes potential points of failure and speeds up workflows. Future-proofing A standard theme structure remains compatible with WordPress core updates and developer expectations, even a decade later. In my experience, minimal setups foster easier collaboration and faster problem-solving. They focus on solving the problem rather than adhering to overly opinionated patterns. Real World Example Like many things, this all sounds great and makes sense in theory, but what does it look like in practice? Seeing is believing, so I’ve created a minimal theme that exemplifies some of the concepts I’ve described here. This theme is a work in progress, and there are plenty of areas where it needs work. It provides the top features that custom WordPress developers seem to want most in a theme framework. View Code in GitHub → Modern Features Before we dive in, I’ll list out some of the key benefits of what’s going on in this theme. Above all of these, working minimally and keeping things simple and easy to understand is by far the largest benefit, in my opinion. A watch task that compiles and reloads in under 100ms; Sass for CSS preprocessing coupled with CSS written in BEM syntax; Native ES modules; Composer package management; Twig view templating; View-controller pattern; Namespaced PHP for isolation; Built-in support for the Advanced Custom Fields plugin; Global context variables for common WordPress data: site_url, site_description, site_url, theme_dir, theme_url, primary_nav, ACF custom fields, the_title(), the_content(). Templating Language Twig is included with this theme, and it is used to load a small set of commonly used global context variables such as theme URL, theme directory, site name, site URL, and so on. It also includes some core functions as well, like the_content(), the_title(), and others you’d routinely often use during the process of creating a custom theme. These global context variables and functions are available for all URLs. While it could be argued that Twig is an unnecessary additional abstraction layer when we’re trying to establish a minimal WordPress setup, I chose to include it because this type of abstraction is included in Sage. But it’s also for a few other important reasons: Old, Dependable, and Stable. You won’t need to worry about any future breaking changes in future versions, and it’s widely in use today. All the features I commonly see used in Sage Blade templates can easily be handled with Twig similarly. There really isn’t anything you can do with Blade that isn’t possible with Twig. Blade is a great templating language, but it’s best suited for Laravel, in my opinion. BladeOne does provide a good way to use it as a standalone templating engine, but even then, it’s still not as performant under pressure as Twig. Twig’s added performance, when used with small, efficient contexts, allows us to avoid the complexity that comes with caching view output. Compile-on-the-fly Twig is very close to the same speed as raw PHP in this use case. Most importantly, Twig was built to be portable. It can be installed with composer and used within the theme with just 55 lines of code. Now, in a real project, this would probably be more than 55 lines, but either way, it is, without a doubt, much easier to understand and work with than Blade. Blade was built for use in Laravel, and it’s just not nearly as portable. It will be significantly easier to identify issues, track them down with a direct stack trace, and fix them with Twig. The view context in this theme is deliberately kept sparse, during a site build you’ll add what you specifically need for a particular site. A lean context for your views helps with performance and workflow. Models & Controllers The template hierarchy follows the patterns of good ol’ WordPress, and while some developers don’t like this, it is undoubtedly the most widely accepted and commonly understood standard. Each standard theme file uses a model where you define your data structures with PHP and hand off the theme as the context to a .twig view file. Developers like the structure of separating server-side logic from a template, and in a classic MVC/MVVC pattern, we have our model, view, and controller. Here, I’m using the standard WordPress theme templates as models. Currently, template files include some useful basics. You’re likely familiar with these standard templates, but I’ll list them here for posterity: 404.php: Displays a custom “Page Not Found” message when a visitor tries to access a page that doesn’t exist. archive.php: Displays a list of posts from a particular archive, such as a category, date, or tag archive. author.php: Displays a list of posts by a specific author, along with the author’s information. category.php: Displays a list of posts from a specific category. footer.php: Contains the footer section of the theme, typically including closing HTML tags and widgets or navigation in the footer area. front-page.php: The template used for the site’s front page, either static or a blog, depending on the site settings. functions.php: Adds custom functionality to the theme, such as registering menus and widgets or adding theme support for features like custom logos or post thumbnails. header.php: Contains the header section of the theme, typically including the site’s title, meta tags, and navigation menu. index.php: The fallback template for all WordPress pages is used if no other more specific template (like category.php or single.php) is available. page.php: Displays individual static pages, such as “About” or “Contact” pages. screenshot.png: An image of the theme’s design is shown in the WordPress theme selector to give users a preview of the theme’s appearance. search.php: Displays the results of a search query, showing posts or pages that match the search terms entered by the user. single.php: Displays individual posts, often used for blog posts or custom post types. tag.php: Displays a list of posts associated with a specific tag. Extremely Fast Build Process For SCSS And JavaScript The build is curiously different in this theme, but out of the box, you can compile SCSS to CSS, work with native JavaScript modules, and have a live reload watch process with a tiny footprint. Look inside the bin/*.js files, and you’ll see everything that’s happening. There are just two commands here, and all web developers should be familiar with them: Watch While developing, it will reload or inject JavaScript and CSS changes into the browser automatically using a Browsersync. Build This task compiles all top-level *.scss files efficiently. There’s room for improvement, but keep in mind this theme serves as a concept. Now for a curveball: there is no compile process for JavaScript. File changes will still be injected into the browser with hot module replacement during watch mode, but we don’t need to compile anything. WordPress will load theme JavaScript as native ES modules, using WordPress 6.5’s support for ES modules. My reasoning is that many sites now pass through Cloudflare, so modern compression is handled for JavaScript automatically. Many specialized WordPress hosts do this as well. When comparing minification to GZIP, it’s clear that minification provides trivial gains in file reduction. The vast majority of file reduction is provided by CDN and server compression. Based on this, I believe the benefits of a fast workflow far outweigh the additional overhead of pulling in build steps for webpack, Rollup, or other similar packaging tools. We’re fortunate that the web fully supports ES modules today, so there is really no reason why we should need to compile JavaScript at all if we’re not using a JavaScript framework like Vue, React, or Svelte. A Contrarian Approach My perspective and the ideas I’ve shared here are undoubtedly contrarian. Like anything alternative, this is bound to ruffle some feathers. Frameworks like Sage are celebrated in developer circles, with strong communities behind them. For certain use cases — like large-scale, enterprise-level projects with dedicated development teams — they may indeed be the right fit. For the vast majority of WordPress projects I encounter, the added complexity creates more problems than it solves. As developers, our goal should be to build solutions that are not only functional and performant but also maintainable and approachable for the next person who inherits them. Simplicity, in my view, is underrated in modern web development. A minimal WordPress setup, tailored to the specific needs of the project without unnecessary abstraction, is often the leaner, more sustainable choice. Conclusion Inheriting framework-based projects has taught me invaluable lessons about the real-world impact of theme frameworks. While they may impress in an initial pitch or during development, the long-term consequences of added complexity often outweigh the benefits. By adopting a minimal WordPress approach, we can build sites that are easier to maintain, faster to onboard new developers, and more resilient to change. Modern tools have their place, but minimalism never goes out of style. When you choose simplicity, you choose a codebase that works today, tomorrow, and years down the line. Isn’t that what great web development is all about?

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    Sunshine And March Vibes (2025 Wallpapers Edition)

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      Do you need a little inspiration boost? Well, then our new batch of desktop wallpapers is for you. Designed by the community for the community, the wallpapers in this collection are the perfect opportunity to get your desktop ready for spring — and, who knows, maybe they’ll spark some new ideas, too. Enjoy!

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      With the days getting noticeably longer in the northern hemisphere, the sun coming out, and the flowers blooming, March fuels us with fresh energy. And even if spring is far away in your part of the world, you might feel that 2025 has gained full speed by now — the perfect opportunity to put all those plans you’ve made and ideas you’ve been carrying around to action! To cater for some extra inspiration this March, artists and designers from across the globe once again challenged their creative skills and designed a new batch of desktop wallpapers to accompany you through the month. As every month, you’ll find their artworks compiled below — together with some timeless March favorites from our archives that are just too good to be forgotten. This post wouldn’t exist without the kind support of our wonderful community who diligently contributes their designs each month anew to keep the steady stream of wallpapers flowing. So, a huge thank-you to everyone who shared their artwork with us this time around! If you, too, would like to get featured in one of our upcoming wallpapers posts, please don’t hesitate to join in. We can’t wait to see what you’ll come up with! Happy March! You can click on every image to see a larger preview. We respect and carefully consider the ideas and motivation behind each and every artist’s work. This is why we give all artists the full freedom to explore their creativity and express emotions and experience through their works. This is also why the themes of the wallpapers weren’t anyhow influenced by us but rather designed from scratch by the artists themselves. Submit your wallpaper design! 👩‍🎨 Feeling inspired? We are always looking for creative talent and would love to feature your desktop wallpaper in one of our upcoming posts. Join in ↬ Bee-utiful Smile Designed by Doreen Bethge from Germany. preview with calendar: 640x480, 800x600, 1024x768, 1152x864, 1280x720, 1280x800, 1280x960, 1400x1050, 1440x900, 1600x1200, 1680x1050, 1920x1080, 1920x1200, 1920x1440, 2560x1440, 3200x2000 without calendar: 640x480, 800x600, 1024x768, 1152x864, 1280x720, 1280x800, 1280x960, 1400x1050, 1440x900, 1600x1200, 1680x1050, 1920x1080, 1920x1200, 1920x1440, 2560x1440, 3200x2000 Coffee Break Designed by Ricardo Gimenes from Spain. preview with calendar: 640x480, 800x480, 800x600, 1024x768, 1024x1024, 1152x864, 1280x720, 1280x800, 1280x960, 1280x1024, 1366x768, 1400x1050, 1440x900, 1600x1200, 1680x1050, 1680x1200, 1920x1080, 1920x1200, 1920x1440, 2560x1440, 3840x2160 without calendar: 640x480, 800x480, 800x600, 1024x768, 1024x1024, 1152x864, 1280x720, 1280x800, 1280x960, 1280x1024, 1366x768, 1400x1050, 1440x900, 1600x1200, 1680x1050, 1680x1200, 1920x1080, 1920x1200, 1920x1440, 2560x1440, 3840x2160 Rosa Parks “March, the month of transition between winter and spring, is dedicated to Rosa Parks and her great phrase: ‘You must never be fearful about what you are doing when it is right.’” — Designed by Veronica Valenzuela from Spain. preview with calendar: 640x480, 800x480, 1024x768, 1280x720, 1280x800, 1440x900, 1600x1200, 1920x1080, 1920x1440, 2560x1440 without calendar: 640x480, 800x480, 1024x768, 1280x720, 1280x800, 1440x900, 1600x1200, 1920x1080, 1920x1440, 2560x1440 So Tire Designed by Ricardo Gimenes from Spain. preview with calendar: 640x480, 800x480, 800x600, 1024x768, 1024x1024, 1152x864, 1280x720, 1280x800, 1280x960, 1280x1024, 1366x768, 1400x1050, 1440x900, 1600x1200, 1680x1050, 1680x1200, 1920x1080, 1920x1200, 1920x1440, 2560x1440, 3840x2160 without calendar: 640x480, 800x480, 800x600, 1024x768, 1024x1024, 1152x864, 1280x720, 1280x800, 1280x960, 1280x1024, 1366x768, 1400x1050, 1440x900, 1600x1200, 1680x1050, 1680x1200, 1920x1080, 1920x1200, 1920x1440, 2560x1440, 3840x2160 Time To Wake Up “Rays of sunlight had cracked into the bear’s cave. He slowly opened one eye and caught a glimpse of nature in blossom. Is it spring already? Oh, but he is so sleepy. He doesn’t want to wake up, not just yet. So he continues dreaming about those sweet sluggish days while everything around him is blooming.” — Designed by PopArt Studio from Serbia. preview without calendar: 320x480, 640x480, 800x480, 800x600, 1024x768, 1024x1024, 1152x864, 1280x720, 1280x800, 1280x960, 1280x1024, 1366x768, 1400x1050, 1440x900, 1600x1200, 1680x1050, 1680x1200, 1920x1080, 1920x1200, 1920x1440, 2560x1440 Music From The Past Designed by Ricardo Gimenes from Spain. preview without calendar: 640x480, 800x480, 800x600, 1024x768, 1024x1024, 1152x864, 1280x720, 1280x800, 1280x960, 1280x1024, 1366x768, 1400x1050, 1440x900, 1600x1200, 1680x1050, 1920x1080, 1920x1200, 1920x1440, 2560x1440, 3840x2160 Northern Lights “Spring is getting closer, and we are waiting for it with open arms. This month, we want to enjoy discovering the northern lights. To do so, we are going to Alaska, where we have the faithful company of our friend White Fang.” — Designed by Veronica Valenzuela Jimenez from Spain. preview without calendar: 640x480, 800x480, 1024x768, 1280x720, 1280x800, 1440x900, 1600x1200, 1920x1080, 1920x1440, 2560x1440 Queen Bee “Spring is coming! Birds are singing, flowers are blooming, bees are flying… Enjoy this month!” — Designed by Melissa Bogemans from Belgium. preview without calendar: 320x480, 640x480, 800x480, 800x600, 1024x768, 1024x1024, 1152x864, 1280x720, 1280x800, 1280x960, 1280x1024, 1400x1050, 1440x900, 1600x1200, 1680x1050, 1680x1200, 1920x1080, 1920x1200, 1920x1440, 2560x1440 Botanica Designed by Vlad Gerasimov from Georgia. preview without calendar: 320x480, 640x480, 800x480, 800x600, 1024x768, 1024x1024, 1152x864, 1280x720, 1280x800, 1280x960, 1280x1024, 1400x1050, 1440x900, 1600x1200, 1680x1050, 1680x1200, 1920x1080, 1920x1200, 1920x1440, 2560x1440 Let’s Spring “After some freezing months, it’s time to enjoy the sun and flowers. It’s party time, colours are coming, so let’s spring!” — Designed by Colorsfera from Spain. preview without calendar: 320x480, 1024x768, 1024x1024, 1280x800, 1280x960, 1280x1024, 1400x1050, 1440x900, 1600x1200, 1680x1050, 1680x1200, 1920x1080, 1920x1200, 1920x1440, 2560x1440 Spring Bird Designed by Nathalie Ouederni from France. preview without calendar: 1024x768, 1280x1024, 1440x900, 1680x1200, 1920x1200, 2560x1440 Explore The Forest “This month, I want to go to the woods and explore my new world in sunny weather.” — Designed by Zi-Cing Hong from Taiwan. preview without calendar: 1024x768, 1152x864, 1280x720, 1280x800, 1280x960, 1366x768, 1400x1050, 1440x900, 1600x1200, 1680x1050, 1920x1080, 1920x1200, 1920x1440, 2560x1440 Tacos To The Moon And Back Designed by Ricardo Gimenes from Spain. preview without calendar: 640x480, 800x480, 800x600, 1024x768, 1024x1024, 1152x864, 1280x720, 1280x800, 1280x960, 1280x1024, 1366x768, 1400x1050, 1440x900, 1600x1200, 1680x1050, 1680x1200, 1920x1080, 1920x1200, 1920x1440, 2560x1440, 3840x2160 Daydreaming “Daydreaming of better things, of lovely things, of saddening things.” — Designed by Bhabna Basak from India. preview without calendar: 1440x900, 1600x1200, 1680x1050, 1680x1200, 1920x1080, 1920x1200, 1920x1440, 2560x1440 Ballet “A day, even a whole month, isn’t enough to show how much a woman should be appreciated. Dear ladies, any day or month are yours if you decide so.” — Designed by Ana Masnikosa from Belgrade, Serbia. preview without calendar: 320x480, 640x480, 800x480, 800x600, 1024x768, 1024x1024, 1152x864, 1280x720, 1280x800, 1280x960, 1280x1040, 1400x1050, 1440x900, 1600x1200, 1680x1050, 1680x1200, 1920x1080, 1920x1200, 1920x1440, 2560x1440 Awakening “I am the kind of person who prefers the cold but I do love spring since it’s the magical time when flowers and trees come back to life and fill the landscape with beautiful colors.” — Designed by Maria Keller from Mexico. preview without calendar: 320x480, 640x480, 640x1136, 750x1334, 800x480, 800x600, 1024x768, 1024x1024, 1152x864, 1242x2208, 1280x720, 1280x800, 1280x960, 1280x1024, 1366x768, 1400x1050, 1440x900, 1600x1200, 1680x1050, 1680x1200, 1920x1080, 1920x1200, 1920x1440, 2560x1440 MARCHing Forward “If all you want is a little orange dinosaur MARCHing (okay, I think you get the pun) across your monitor, this wallpaper was made just for you! This little guy is my design buddy at the office and sits by (and sometimes on top of) my monitor. This is what happens when you have designer’s block and a DSLR.” — Designed by Paul Bupe Jr from Statesboro, GA. preview without calendar: 1024x768, 1280x1024, 1440x900, 1920x1080, 1920x1200, 2560x1440 Jingzhe “Jīngzhé is the third of the 24 solar terms in the traditional East Asian calendars. The word 驚蟄 means ‘the awakening of hibernating insects’. 驚 is ‘to start’ and 蟄 means ‘hibernating insects’. Traditional Chinese folklore says that during Jingzhe, thunderstorms will wake up the hibernating insects, which implies that the weather is getting warmer.” — Designed by Sunny Hong from Taiwan. preview without calendar: 800x600, 1280x720, 1280x1024, 1366x768, 1400x1050, 1680x1200, 1920x1080, 2560x1440 Fresh Lemons Designed by Nathalie Ouederni from France. preview without calendar: 320x480, 1024x768, 1280x1024, 1440x900, 1600x1200, 1680x1200, 1920x1200, 2560x1440 Pizza Time “Who needs an excuse to look at pizza all month?” — Designed by James Mitchell from the United Kingdom. preview without calendar: 1280x720, 1280x800, 1366x768, 1440x900, 1680x1050, 1920x1080, 1920x1200, 2560x1440, 2880x1800 Questions “Doodles are slowly becoming my trademark, so I just had to use them to express this phrase I’m fond of recently. A bit enigmatic, philosophical. Inspiring, isn’t it?” — Designed by Marta Paderewska from Poland. preview without calendar: 640x480, 800x480, 800x600, 1024x768, 1024x1024, 1152x864, 1280x720, 1280x800, 1280x960, 1280x1024, 1366x768, 1400x1050, 1440x900, 1600x1200, 1680x1050, 1680x1200, 1920x1080, 1920x1200, 1920x1440, 2560x1440 The Unknown “I made a connection, between the dark side and the unknown lighted and catchy area.” — Designed by Valentin Keleti from Romania. preview without calendar: 320x480, 640x480, 800x480, 800x600, 1024x768, 1024x1024, 1152x864, 1280x720, 1280x800, 1280x960, 1280x1024, 1366x768, 1400x1050, 1440x900, 1600x1200, 1680x1050, 1680x1200, 1920x1080, 1920x1200, 1920x1440, 2560x1440 Waiting For Spring “As days are getting longer again and the first few flowers start to bloom, we are all waiting for spring to finally arrive.” — Designed by Naioo from Germany. preview without calendar: 1280x800, 1366x768, 1440x900, 1680x1050, 1920x1080, 1920x1200 St. Patrick’s Day “On the 17th March, raise a glass and toast St. Patrick on St. Patrick’s Day, the Patron Saint of Ireland.” — Designed by Ever Increasing Circles from the United Kingdom. preview without calendar: 320x480, 640x480, 800x480, 800x600, 1024x768, 1024x1024, 1080x1080, 1152x864, 1280x720, 1280x800, 1280x960, 1280x1024, 1366x768, 1400x1050, 1440x900, 1600x1200, 1680x1050, 1680x1200, 1920x1080, 1920x1200, 1920x1440, 2560x1440 Spring Is Coming “This March, our calendar design epitomizes the heralds of spring. Soon enough, you’ll be waking up to the singing of swallows, in a room full of sunshine, filled with the empowering smell of daffodil, the first springtime flowers. Spring is the time of rebirth and new beginnings, creativity and inspiration, self-awareness, and inner reflection. Have a budding, thriving spring!” — Designed by PopArt Studio from Serbia. preview without calendar: 320x480, 640x480, 800x480, 800x600, 1024x768, 1024x1024, 1152x864, 1280x720, 1280x800, 1280x960, 1280x1024, 1366x768, 1440x900, 1440x1050, 1600x1200, 1680x1050, 1680x1200, 1920x1080, 1920x1200, 1920x1440, 2560x1440 Happy Birthday Dr. Seuss! “March 2nd marks the birthday of the most creative and extraordinary author ever, Dr. Seuss! I have included an inspirational quote about learning to encourage everyone to continue learning new things every day.” — Designed by Safia Begum from the United Kingdom.</p preview without calendar: 800x450, 1280x720, 1366x768, 1440x810, 1600x900, 1680x945, 1920x1080, 2560x1440 Wake Up! “Early spring in March is for me the time when the snow melts, everything isn’t very colorful. This is what I wanted to show. Everything comes to life slowly, as this bear. Flowers are banal, so instead of a purple crocus we have a purple bird-harbinger.” — Designed by Marek Kedzierski from Poland. preview without calendar: 320x480, 1024x768, 1280x720, 1280x800, 1280x960, 1400x1050, 1600x1200, 1680x1050, 1920x1080, 1920x1200, 2560x1440 Spring Is Inevitable “Spring is round the corner. And very soon plants will grow on some other planets too. Let’s be happy about a new cycle of life.” — Designed by Igor Izhik from Canada. preview without calendar: 1024x768, 1024x1024, 1152x864, 1280x720, 1280x800, 1280x960, 1280x1024, 1400x1050, 1440x900, 1600x1200, 1680x1050, 1680x1200, 1920x1080, 1920x1200, 1920x1440, 2560x1440, 2560x1600 Traveling To Neverland “This month we become children and we travel with Peter Pan. Let’s go to Neverland!” — Designed by Veronica Valenzuela from Spain. preview without calendar: 640x480, 800x480, 1024x768, 1280x720, 1280x800, 1440x900, 1600x1200, 1920x1080, 1920x1440, 2560x1440 Let’s Get Outside Designed by Lívia Lénárt from Hungary. preview without calendar: 1024x768, 1280x1024, 1366x768, 1600x1200, 1680x1200, 1920x1080, 1920x1200, 2560x1440

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      The Human Element: Using Research And Psychology To Elevate Data Storytelling

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        Effective data storytelling isn’t a black box. By integrating UX research & psychology, you can craft more impactful and persuasive narratives. Victor Yocco and Angelica Lo Duca outline a five-step framework that provides a roadmap for creating data stories that resonate with audiences on both a cognitive and emotional level.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        Data storytelling is a powerful communication tool that combines data analysis with narrative techniques to create impactful stories. It goes beyond presenting raw numbers by transforming complex data into meaningful insights that can drive decisions, influence behavior, and spark action. When done right, data storytelling simplifies complex information, engages the audience, and compels them to act. Effective data storytelling allows UX professionals to effectively communicate the “why” behind their design choices, advocate for user-centered improvements, and ultimately create more impactful and persuasive presentations. This translates to stronger buy-in for research initiatives, increased alignment across teams, and, ultimately, products and experiences that truly meet user needs. For instance, The New York Times’ Snow Fall data story (Figure 1) used data to immerse readers in the tale of a deadly avalanche through interactive visuals and text, while The Guardian’s The Counted (Figure 2) powerfully illustrated police violence in the U.S. by humanizing data through storytelling. These examples show that effective data storytelling can leave lasting impressions, prompting readers to think differently, act, or make informed decisions. The importance of data storytelling lies in its ability to: Simplify complexity It makes data understandable and actionable. Engage and persuade Emotional and cognitive engagement ensures audiences not only understand but also feel compelled to act. Bridge gaps Data storytelling connects the dots between information and human experience, making the data relevant and relatable. While there are numerous models of data storytelling, here are a few high-level areas of focus UX practitioners should have a grasp on: Narrative Structures: Traditional storytelling models like the hero’s journey (Vogler, 1992) or the Freytag pyramid (Figure 3) provide a backbone for structuring data stories. These models help create a beginning, rising action, climax, falling action, and resolution, keeping the audience engaged. Data Visualization: Broadly speaking, these are the tools and techniques for visualizing data in our stories. Interactive charts, maps, and infographics (Cairo, 2016) transform raw data into digestible visuals, making complex information easier to understand and remember. Narrative Structures For Data Moving beyond these basic structures, let’s explore how more sophisticated narrative techniques can enhance the impact of data stories: The Three-Act Structure This approach divides the data story into setup, confrontation, and resolution. It helps build context, present the problem or insight, and offer a solution or conclusion (Few, 2005). The Hero’s Journey (Data Edition) We can frame a data set as a problem that needs a hero to overcome. In this case, the hero is often the audience or the decision-maker who needs to use the data to solve a problem. The data itself becomes the journey, revealing challenges, insights, and, ultimately, a path to resolution. Example: Presenting data on declining user engagement could follow the hero’s journey. The “call to adventure” is the declining engagement. The “challenges” are revealed through data points showing where users are dropping off. The “insights” are uncovered through further analysis, revealing the root causes. The “resolution” is the proposed solution, supported by data, that the audience (the hero) can implement. Problems With Widely Used Data Storytelling Models Many data storytelling models follow a traditional, linear structure: data selection, audience tailoring, storyboarding with visuals, and a call to action. While these models aim to make data more accessible, they often fail to engage the audience on a deeper level, leading to missed opportunities. This happens because they prioritize the presentation of data over the experience of the audience, neglecting how different individuals perceive and process information. While existing data storytelling models adhere to a structured and technically correct approach to data creation, they often fall short of fully analyzing and understanding their audience. This gap weakens their overall effectiveness and impact. Cognitive Overload Presenting too much data without context or a clear narrative overwhelms the audience. Instead of enlightenment, they experience confusion and disengagement. It’s like trying to drink from a firehose; the sheer volume becomes counterproductive. This overload can be particularly challenging for individuals with cognitive differences who may require information to be presented in smaller, more digestible chunks. Emotional Disconnect Data-heavy presentations often fail to establish an emotional connection, which is crucial for driving audience engagement and action. People are more likely to remember and act upon information that resonates with their feelings and values. Lack of Personalization Many data stories adopt a one-size-fits-all approach. Without tailoring the narrative to specific audience segments, the impact is diluted. A message that resonates with a CEO might not land with frontline employees. Over-Reliance on Visuals While visuals are essential for simplifying data, they are insufficient without a cohesive narrative to provide context and meaning, and they may not be accessible to all audience members. These shortcomings reveal a critical flaw: while current models successfully follow a structured data creation process, they often neglect the deeper, audience-centered analysis required for actual storytelling effectiveness. To bridge this gap, Data storytelling must evolve beyond simply presenting information — it should prioritize audience understanding, engagement, and accessibility at every stage. Improving On Traditional Models Traditional models can be improved by focusing more on the following two critical components: Audience understanding: A greater focus can be concentrated on who the audience is, what they need, and how they perceive information. Traditional models should consider the unique characteristics and needs of specific audiences. This lack of audience understanding can lead to data stories that are irrelevant, confusing, or even misleading. Effective data storytelling requires a deep understanding of the audience’s demographics, psychographics, and information needs. This includes understanding their level of knowledge about the topic, their prior beliefs and attitudes, and their motivations for seeking information. By tailoring the data story to a specific audience, storytellers can increase engagement, comprehension, and persuasion. Psychological principles: These models could be improved with insights from psychology that explain how people process information and make decisions. Without these elements, even the most beautifully designed data story may fall flat. Traditional models of data storytelling can be improved with two critical components that are essential for creating impactful and persuasive narratives: audience understanding and psychological principles. By incorporating audience understanding and psychological principles into their storytelling process, data storytellers can create more effective and engaging narratives that resonate with their audience and drive desired outcomes. Persuasion In Data Storytelling All storytelling involves persuasion. Even if it’s a poorly told story and your audience chooses to ignore your message, you’ve persuaded them to do that. When your audience feels that you understand them, they are more likely to be persuaded by your message. Data-driven stories that speak to their hearts and minds are more likely to drive action. You can frame your message effectively when you have a deeper understanding of your audience. Applying Psychological Principles To Data Storytelling Humans process information based on psychological cues such as cognitive ease, social proof, and emotional appeal. By incorporating these principles, data storytellers can make their narratives more engaging, memorable, and persuasive. Psychological principles help data storytellers tap into how people perceive, interpret, and remember information. The Theory of Planned Behavior While there is no single truth when it comes to how human behavior is created or changed, it is important for a data storyteller to use a theoretical framework to ensure they address the appropriate psychological factors of their audience. The Theory of Planned Behavior (TPB) is a commonly cited theory of behavior change in academic psychology research and courses. It’s useful for creating a reasonably effective framework to collect audience data and build a data story around it. The TPB (Ajzen 1991) (Figure 5) aims to predict and explain human behavior. It consists of three key components: Attitude This refers to the degree to which a person has a favorable or unfavorable evaluation of the behavior in question. An example of attitudes in the TPB is a person’s belief about the importance of regular exercise for good health. If an individual strongly believes that exercise is beneficial, they are likely to have a favorable attitude toward engaging in regular physical activity. Subjective Norms These are the perceived social pressures to perform or not perform the behavior. Keeping with the exercise example, this would be how a person thinks their family, peers, community, social media, and others perceive the importance of regular exercise for good health. Perceived Behavioral Control This component reflects the perceived ease or difficulty of performing the behavior. For our physical activity example, does the individual believe they have access to exercise in terms of time, equipment, physical capability, and other potential aspects that make them feel more or less capable of engaging in the behavior? As shown in Figure 5, these three components interact to create behavioral intentions, which are a proxy for actual behaviors that we often don’t have the resources to measure in real-time with research participants (Ajzen, 1991). UX researchers and data storytellers should develop a working knowledge of the TPB or another suitable psychological theory before moving on to measure the audience’s attitudes, norms, and perceived behavioral control. We have included additional resources to support your learning about the TPB in the references section of this article. How To Understand Your Audience And Apply Psychological Principles OK, we’ve covered the importance of audience understanding and psychology. These two principles serve as the foundation of the proposed model of storytelling we’re putting forth. Let’s explore how to integrate them into your storytelling process. Introducing The Audience Research Informed Data Storytelling Model (ARIDSM) At the core of successful data storytelling lies a deep understanding of your audience’s psychology. Here’s a five-step process to integrate UX research and psychological principles effectively into your data stories: Step 1: Define Clear Objectives Before diving into data, it’s crucial to establish precisely what you aim to achieve with your story. Do you want to inform, persuade, or inspire action? What specific message do you want your audience to take away? Why it matters: Defining clear objectives provides a roadmap for your storytelling journey. It ensures that your data, narrative, and visuals are all aligned toward a common goal. Without this clarity, your story risks becoming unfocused and losing its impact. How to execute Step 1: Start by asking yourself: What is the core message I want to convey? What do I want my audience to think, feel, or do after experiencing this story? How will I measure the success of my data story? Frame your objectives using action verbs and quantifiable outcomes. For example, instead of “raise awareness about climate change,” aim to “persuade 20% of the audience to adopt one sustainable practice.” Example: Imagine you’re creating a data story about employee burnout. Your objective might be to convince management to implement new policies that promote work-life balance, with the goal of reducing reported burnout cases by 15% within six months. Step 2: Conduct UX Research To Understand Your Audience This step involves gathering insights about your audience: their demographics, needs, motivations, pain points, and how they prefer to consume information. Why it matters: Understanding your audience is fundamental to crafting a story that resonates. By knowing their preferences and potential biases, you can tailor your narrative and data presentation to capture their attention and ensure the message is clearly understood. How to execute Step 2: Employ UX research methods like surveys, interviews, persona development, and testing the message with potential audience members. Example: If your data story aims to encourage healthy eating habits among college students, your research might conduct a survey of students to determine what types of attitudes exist towards specific types of healthy foods for eating, to apply that knowledge in your data story. Step 3: Analyze and Select Relevant Audience Data This step bridges the gap between raw data and meaningful insights. It involves exploring your data to identify patterns, trends, and key takeaways that support your objectives and resonate with your audience. Why it matters: Careful data analysis ensures that your story is grounded in evidence and that you’re using the most impactful data points to support your narrative. This step adds credibility and weight to your story, making it more convincing and persuasive. How to execute Step 3: Clean and organize your data. Ensure accuracy and consistency before analysis. Identify key variables and metrics. This will be determined by the psychological principle you used to inform your research. Using the TPB, we might look closely at how we measured social norms to understand directionally how the audience perceives social norms around the topic of the data story you are sharing, allowing you to frame your call to action in ways that resonate with these norms. You might run a variety of statistics at this point, including factor analysis to create groups based on similar traits, t-tests to determine if averages on your measurements are significantly different between groups, and correlations to see if there might be an assumed direction between scores on various items. Example: If your objective is to demonstrate the effectiveness of a new teaching method, analyzing how your audience perceives their peers to be open to adopting new methods, their belief that they are in control over the decision to use a new teaching method, and their attitude towards the effectiveness of their current teaching methods to create groups that have various levels of receptivity in trying new methods, allowing you to later tailor your data story for each group. Step 4: Apply The Theory of Planned Behavior Or Your Psychological Principle Of Choice [Done Simultaneous With Step 3] In this step, you will see that The Theory of Planned Behavior (TPB) provides a robust framework for understanding the factors that drive human behavior. It posits that our intentions, which are the strongest predictors of our actions, are shaped by three core components: attitudes, subjective norms, and perceived behavioral control. By consciously incorporating these elements into your data story, you can significantly enhance its persuasive power. Why it matters: The TPB offers valuable insights into how people make decisions. By aligning your narrative with these psychological drivers, you increase the likelihood of influencing your audience’s intentions and, ultimately, their behavior. This step adds a layer of strategic persuasion to your data storytelling, making it more impactful and effective. How to execute Step 4: Here’s how to leverage the TPB in your data story: Influence Attitudes: Present data and evidence that highlight the positive consequences of adopting the desired behavior. Frame the behavior as beneficial, valuable, and aligned with the audience’s values and aspirations. This is where having a deep knowledge of the audience is helpful. Let’s imagine you are creating a data story on exercise and your call to action promoting exercise daily. If you know your audience has a highly positive attitude towards exercise, you can capitalize on that and frame your language around the benefits of exercising, increasing exercise, or specific exercises that might be best suited for the audience. It’s about framing exercise not just as a physical benefit but as a holistic improvement to their life. You can also tie it to their identity, positioning exercise as an integral part of living the kind of life they aspire to. Shape Subjective Norms: Demonstrate that the desired behavior is widely accepted and practiced by others, especially those the audience admires or identifies with. Knowing ahead of time if your audience thinks daily exercise is something their peers approve of or engage in will allow you to shape your messaging accordingly. Highlight testimonials, success stories, or case studies from individuals who mirror the audience’s values. If you were to find that the audience does not consider exercise to be normative amongst peers, you would look for examples of similar groups of people who do exercise. For example, if your audience is in a certain age group, you might focus on what data you have that supports a large percentage of those in their age group engaging in exercise. Enhance Perceived Behavioral Control: Address any perceived barriers to adopting the desired behavior and provide practical solutions. For instance, when promoting daily exercise, it’s important to acknowledge the common obstacles people face — lack of time, resources, or physical capability — and demonstrate how these can be overcome. Step 5: Craft A Balanced And Persuasive Narrative This is where you synthesize your data, audience insights, psychological principles (including the TPB), and storytelling techniques into a compelling and persuasive narrative. It’s about weaving together the logical and emotional elements of your story to create an experience that resonates with your audience and motivates them to act. Why it matters: A well-crafted narrative transforms data from dry statistics into a meaningful and memorable experience. It ensures that your audience not only understands the information but also feels connected to it on an emotional level, increasing the likelihood of them internalizing the message and acting upon it. How to execute Step 5: Structure your story strategically: Use a clear narrative arc that guides your audience through the information. Begin by establishing the context and introducing the problem, then present your data-driven insights in a way that supports your objectives and addresses the TPB components. Conclude with a compelling call to action that aligns with the attitudes, norms, and perceived control you've cultivated throughout the narrative. Example: In a data story about promoting exercise, you could: Determine what stories might be available using the data you have collected or obtained. In this example, let’s say you work for a city planning office and have data suggesting people aren’t currently biking as frequently as they could, even if they are bike owners. Begin with a relatable story about lack of exercise and its impact on people’s lives. Then, present data on the benefits of cycling, highlighting its positive impact on health, socializing, and personal feelings of well-being (attitudes). Integrate TPB elements: Showcase stories of people who have successfully incorporated cycling into their daily commute (subjective norms). Provide practical tips on bike safety, route planning, and finding affordable bikes (perceived behavioral control). Use infographics to compare commute times and costs between driving and cycling. Show maps of bike-friendly routes and visually appealing images of people enjoying cycling. Call to action: Encourage the audience to try cycling for a week and provide links to resources like bike share programs, cycling maps, and local cycling communities. Evaluating The Method Our next step is to test our hypothesis that incorporating audience research and psychology into creating a data story will lead to more powerful results. We have conducted preliminary research using messages focused on climate change, and our results suggest some support for our assertion. We purposely chose a controversial topic because we believe data storytelling can be a powerful tool. If we want to truly realize the benefits of effective data storytelling, we need to focus on topics that matter. We also know that academic research suggests it is more difficult to shift opinions or generate behavior around topics that are polarizing (at least in the US), such as climate change. We are not ready to share the full results of our study. We will share those in an academic journal and in conference proceedings. Here is a look at how we set up the study and how you might do something similar when either creating a data story using our method or doing your own research to test our model. You will see that it closely aligns with the model itself, with the added steps of testing the message against a control message and taking measurements of the actions the message(s) are likely to generate. Step 1: We chose our topic and the data set we wanted to explore. As I mentioned, we purposely went with a polarizing topic. My academic background was in messaging around conservation issues, so we explored that. We used data from a publicly available data set that states July 2023 was the hottest month ever recorded. Step 2: We identified our audience and took basic measurements. We decided our audience would be members of the general public who do not have jobs working directly with climate data or other relevant fields for climate change scientists. We wanted a diverse range of ages and backgrounds, so we screened for this in our questions on the survey to measure the TPB components as well. We created a survey to measure the elements of the TPB as it relates to climate change and administered the survey via a Google Forms link that we shared directly, on social media posts, and in online message boards related to topics of climate change and survey research. Step 3: We analyzed our data and broke our audience into groups based on key differences. This part required a bit of statistical know-how. Essentially, we entered all of the responses into a spreadsheet and ran a factor analysis to define groups based on shared attributes. In our case, we found two distinct groups for our respondents. We then looked deeper into the individual differences between the groups, e.g., group 1 had a notably higher level of positive attitude towards taking action to remediate climate change. Step 4 [remember this happens simultaneously with step 3]: We incorporated aspects of the TPB in how we framed our data analysis. As we created our groups and looked at the responses to the survey, we made sure to note how this might impact the story for our various groups. Using our previous example, a group with a higher positive attitude toward taking action might need less convincing to do something about climate change and more information on what exactly they can do. Table 1 contains examples of the questions we asked related to the TPB. We used the guidance provided here to generate the survey items to measure the TPB related to climate change activism. Note that even the academic who created the TPB states there are no standardized questions (PDF) validated to measure the concepts for each individual topic. Item Measures Scale How beneficial do you believe individual actions are compared to systemic changes (e.g., government policies) in tackling climate change? Attitude 1 to 5 with 1 being “not beneficial” and 5 being “extremely beneficial” How much do you think the people you care about (family, friends, community) expect you to take action against climate change? Subjective Norms 1 to 5 with 1 being “they do not expect me to take action” and 5 being “they expect me to take action” How confident are you in your ability to overcome personal barriers when trying to reduce your environmental impact? Perceived Behavioral Control 1 to 5 with 1 being “not at all confident” and 5 being “extremely confident” Table 1: Examples of questions we used to measure the TPB factors. We asked multiple questions for each factor and then generated a combined mean score for each component. Step 5: We created data stories aligned with the groups and a control story. We created multiple stories to align with the groups we identified in our audience. We also created a control message that lacked substantial framing in any direction. See below for an example of the control data story (Figure 7) and one of the customized data stories (Figure 8) we created. Step 6: We released the stories and took measurements of the likelihood of acting. Specific to our study, we asked the participants how likely they were to “Click here to LEARN MORE.” Our hypothesis was that individuals would express a notably higher likelihood to want to click to learn more on the data story aligned with their grouping, as compared to the competing group and the control group. Step 7: We analyzed the differences between the preexisting groups and what they stated was their likelihood of acting. As I mentioned, our findings are still preliminary, and we are looking at ways to increase our response rate so we can present statistically substantiated findings. Our initial findings are that we do see small differences between the responses to the tailored data stories and the control data story. This is directionally what we would be expecting to see. If you are going to conduct a similar study or test out your messages, you would also be looking for results that suggest your ARIDS-derived message is more likely to generate the expected outcome than a control message or a non-tailored message. Overall, we feel there is an exciting possibility and that future research will help us refine exactly what is critical about generating a message that will have a positive impact on your audience. We also expect there are better models of psychology to use to frame your measurements and message depending on the audience and topic. For example, you might feel Maslow’s hierarchy of needs is more relevant to your data storytelling. You would want to take measurements related to these needs from your audience and then frame the data story using how a decision might help meet their needs. Elevate Your Data Storytelling Traditional models of data storytelling, while valuable, often fall short of effectively engaging and persuading audiences. This is primarily due to their neglect of crucial aspects such as audience understanding and the application of psychological principles. By incorporating these elements into the data storytelling process, we can create more impactful and persuasive narratives. The five-step framework proposed in this article — defining clear objectives, conducting UX research, analyzing data, applying psychological principles, and crafting a balanced narrative — provides a roadmap for creating data stories that resonate with audiences on both a cognitive and emotional level. This approach ensures that data is not merely presented but is transformed into a meaningful experience that drives action and fosters change. As data storytellers, embracing this human-centric approach allows us to unlock the full potential of data and create narratives that truly inspire and inform. Effective data storytelling isn’t a black box. You can test your data stories for effectiveness using the same research process we are using to test our hypothesis as well. While there are additional requirements in terms of time as a resource, you will make this back in the form of a stronger impact on your audience when they encounter your data story if it is shown to be significantly greater than the impact of a control message or other messages you were considering that don’t incorporate the psychological traits of your audience. Please feel free to use our method and provide any feedback on your experience to the author.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        Human-Centered Design Through AI-Assisted Usability Testing: Reality Or Fiction?

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          Eduard Kuric discusses the significance and role of context in the creation of relevant follow-up questions for unmoderated usability testing, how an AI tasked with interactive follow-up should be validated for its capability to incorporate such context, and what the potential — along with the risks — of AI interaction in usability testing.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          Unmoderated usability testing has been steadily growing more popular with the assistance of online UX research tools. Allowing participants to complete usability testing without a moderator, at their own pace and convenience, can have a number of advantages. The first is the liberation from a strict schedule and the availability of moderators, meaning that a lot more participants can be recruited on a more cost-effective and quick basis. It also lets your team see how users interact with your solution in their natural environment, with the setup of their own devices. Overcoming the challenges of distance and differences in time zones in order to obtain data from all around the globe also becomes much easier. However, forgoing the use of moderators also has its drawbacks. The moderator brings flexibility, as well as a human touch into usability testing. Since they are in the same (virtual) space as the participants, the moderator usually has a good idea of what’s going on. They can react in real-time depending on what they witness the participant do and say. A moderator can carefully remind the participants to vocalize their thoughts. To the participant, thinking aloud in front of a moderator can also feel more natural than just talking to themselves. When the participant does something interesting, the moderator can prompt them for further comment. Meanwhile, a traditional unmoderated study lacks such flexibility. In order to complete tasks, participants receive a fixed set of instructions. Once they are done, they can be asked to complete a static questionnaire, and that’s it. The feedback that the research & design team receives will be completely dependent on what information the participants provide on their own. Because of this, the phrasing of instructions and questions in unmoderated testing is extremely crucial. Although, even if everything is planned out perfectly, the lack of adaptive questioning means that a lot of the information will still remain unsaid, especially with regular people who are not trained in providing user feedback. If the usability test participant misunderstands a question or doesn’t answer completely, the moderator can always ask for a follow-up to get more information. A question then arises: Could something like that be handled by AI to upgrade unmoderated testing? Generative AI could present a new, potentially powerful tool for addressing this dilemma once we consider their current capabilities. Large language models (LLMs), in particular, can lead conversations that can appear almost humanlike. If LLMs could be incorporated into usability testing to interactively enhance the collection of data by conversing with the participant, they might significantly augment the ability of researchers to obtain detailed personal feedback from great numbers of people. With human participants as the source of the actual feedback, this is an excellent example of human-centered AI as it keeps humans in the loop. There are quite a number of gaps in the research of AI in UX. To help with fixing this, we at UXtweak research have conducted a case study aimed at investigating whether AI could generate follow-up questions that are meaningful and result in valuable answers from the participants. Asking participants follow-up questions to extract more in-depth information is just one portion of the moderator’s responsibilities. However, it is a reasonably-scoped subproblem for our evaluation since it encapsulates the ability of the moderator to react to the context of the conversation in real time and to encourage participants to share salient information. Experiment Spotlight: Testing GPT-4 In Real-Time Feedback The focus of our study was on the underlying principles rather than any specific commercial AI solution for unmoderated usability testing. After all, AI models and prompts are being tuned constantly, so findings that are too narrow may become irrelevant in a week or two after a new version gets updated. However, since AI models are also a black box based on artificial neural networks, the method by which they generate their specific output is not transparent. Our results can show what you should be wary of to verify that an AI solution that you use can actually deliver value rather than harm. For our study, we used GPT-4, which at the time of the experiment was the most up-to-date model by OpenAI, also capable of fulfilling complex prompts (and, in our experience, dealing with some prompts better than the more recent GPT-4o). In our experiment, we conducted a usability test with a prototype of an e-commerce website. The tasks involved the common user flow of purchasing a product. Note: See our article published in the International Journal of Human-Computer Interaction for more detailed information about the prototype, tasks, questions, and so on). In this setting, we compared the results with three conditions: A regular static questionnaire made up of three pre-defined questions (Q1, Q2, Q3), serving as an AI-free baseline. Q1 was open-ended, asking the participants to narrate their experiences during the task. Q2 and Q3 can be considered non-adaptive follow-ups to Q1 since they asked participants more directly about usability issues and to identify things that they did not like. The question Q1, serving as a seed for up to three GPT-4-generated follow-up questions as the alternative to Q2 and Q3. All three pre-defined questions, Q1, Q2, and Q3, each used as a seed for its own GPT-4 follow-up. The following prompt was used to generate the follow-up questions: To assess the impact of the AI follow-up questions, we then compared the results on both a quantitative and a qualitative basis. One of the measures that we analyzed is informativeness — ratings of the responses based on how useful they are at elucidating new usability issues encountered by the user. As seen in the figure below, the informativeness dropped significantly between the seed questions and their AI follow-up. The follow-ups rarely helped identify a new issue, although they did help elaborate further details. The emotional reactions of the participants offer another perspective on AI-generated follow-up questions. Our analysis of the prevailing emotional valence based on the phrasing of answers revealed that, at first, the answers started with a neutral sentiment. Afterward, the sentiment shifted toward the negative. In the case of the pre-defined questions Q2 and Q3, this could be seen as natural. While question Seed 1 was open-ended, asking the participants to explain what they did during the task, Q2 and Q3 focused more on the negative — usability issues and other disliked aspects. Curiously, the follow-up chains generally received even more negative receptions than their seed questions, and not for the same reason. Frustration was common as participants interacted with the GPT-4-driven follow-up questions. This is rather critical, considering that frustration with the testing process can sidetrack participants from taking usability testing seriously, hinder meaningful feedback, and introduce a negative bias. A major aspect that participants were frustrated with was redundancy. Repetitiveness, such as re-explaining the same usability issue, was quite common. While pre-defined follow-up questions yielded 27-28% of repeated answers (it’s likely that participants already mentioned aspects they disliked during the open-ended Q1), AI-generated questions yielded 21%. That’s not that much of an improvement, given that the comparison is made to questions that literally could not adapt to prevent repetition at all. Furthermore, when AI follow-up questions were added to obtain more elaborate answers for every pre-defined question, the repetition ratio rose further to 35%. In the variant with AI, participants also rated the questions as significantly less reasonable. Answers to AI-generated questions contained a lot of statements like “I already said that” and “The obvious AI questions ignored my previous responses.” The prevalence of repetition within the same group of questions (the seed question, its follow-up questions, and all of their answers) can be seen as particularly problematic since the GPT-4 prompt had been provided with all the information available in this context. This demonstrates that a number of the follow-up questions were not sufficiently distinct and lacked the direction that would warrant them being asked. Insights From The Study: Successes And Pitfalls To summarize the usefulness of AI-generated follow-up questions in usability testing, there are both good and bad points. Successes: Generative AI (GPT-4) excels at refining participant answers with contextual follow-ups. Depth of qualitative insights can be enhanced. Challenges: Limited capacity to uncover new issues beyond pre-defined questions. Participants can easily grow frustrated with repetitive or generic follow-ups. While extracting answers that are a bit more elaborate is a benefit, it can be easily overshadowed if the lack of question quality and relevance is too distracting. This can potentially inhibit participants’ natural behavior and the relevance of feedback if they’re focusing on the AI. Therefore, in the following section, we discuss what to be careful of, whether you are picking an existing AI tool to assist you with unmoderated usability testing or implementing your own AI prompts or even models for a similar purpose. Recommendations For Practitioners Context is the end-all and be-all when it comes to the usefulness of follow-up questions. Most of the issues that we identified with the AI follow-up questions in our study can be tied to the ignorance of proper context in one shape or another. Based on real blunders that GPT-4 made while generating questions in our study, we have meticulously collected and organized a list of the types of context that these questions were missing. Whether you’re looking to use an existing AI tool or are implementing your own system to interact with participants in unmoderated studies, you are strongly encouraged to use this list as a high-level checklist. With it as the guideline, you can assess whether the AI models and prompts at your disposal can ask reasonable, context-sensitive follow-up questions before you entrust them with interacting with real participants. Without further ado, these are the relevant types of context: General Usability Testing Context. The AI should incorporate standard principles of usability testing in its questions. This may appear obvious, and it actually is. But it needs to be said, given that we have encountered issues related to this context in our study. For example, the questions should not be leading, ask participants for design suggestions, or ask them to predict their future behavior in completely hypothetical scenarios (behavioral research is much more accurate for that). Usability Testing Goal Context. Different usability tests have different goals depending on the stage of the design, business goals, or features being tested. Each follow-up question and the participant’s time used in answering it are valuable resources. They should not be wasted on going off-topic. For example, in our study, we were evaluating a prototype of a website with placeholder photos of a product. When the AI starts asking participants about their opinion of the displayed fake products, such information is useless to us. User Task Context. Whether the tasks in your usability testing are goal-driven or open and exploratory, their nature should be properly reflected in follow-up questions. When the participants have freedom, follow-up questions could be useful for understanding their motivations. By contrast, if your AI tool foolishly asks the participants why they did something closely related to the task (e.g., placing the specific item they were supposed to buy into the cart), you will seem just as foolish by association for using it. Design Context. Detailed information about the tested design (e.g., prototype, mockup, website, app) can be indispensable for making sure that follow-up questions are reasonable. Follow-up questions should require input from the participant. They should not be answerable just by looking at the design. Interesting aspects of the design could also be reflected in the topics to focus on. For example, in our study, the AI would occasionally ask participants why they believed a piece of information that was very prominently displayed in the user interface, making the question irrelevant in context. Interaction Context. If Design Context tells you what the participant could potentially see and do during the usability test, Interaction Context comprises all their actual actions, including their consequences. This could incorporate the video recording of the usability test, as well as the audio recording of the participant thinking aloud. The inclusion of interaction context would allow follow-up questions to build on the information that the participant already provided and to further clarify their decisions. For example, if a participant does not successfully complete a task, follow-up questions could be directed at investigating the cause, even as the participant continues to believe they have fulfilled their goal. Previous Question Context. Even when the questions you ask them are mutually distinct, participants can find logical associations between various aspects of their experience, especially since they don’t know what you will ask them next. A skilled moderator may decide to skip a question that a participant already answered as part of another question, instead focusing on further clarifying the details. AI follow-up questions should be capable of doing the same to avoid the testing from becoming a repetitive slog. Question Intent Context. Participants routinely answer questions in a way that misses their original intent, especially if the question is more open-ended. A follow-up can spin the question from another angle to retrieve the intended information. However, if the participant’s answer is technically a valid reply but only to the word rather than the spirit of the question, the AI can miss this fact. Clarifying the intent could help address this. When assessing a third-party AI tool, a question to ask is whether the tool allows you to provide all of the contextual information explicitly. If AI does not have an implicit or explicit source of context, the best it can do is make biased and untransparent guesses that can result in irrelevant, repetitive, and frustrating questions. Even if you can provide the AI tool with the context (or if you are crafting the AI prompt yourself), that does not necessarily mean that the AI will do as you expect, apply the context in practice, and approach its implications correctly. For example, as demonstrated in our study, when a history of the conversation was provided within the scope of a question group, there was still a considerable amount of repetition. The most straightforward way to test the contextual responsiveness of a specific AI model is simply by conversing with it in a way that relies on context. Fortunately, most natural human conversation already depends on context heavily (saying everything would take too long otherwise), so that should not be too difficult. What is key is focusing on the varied types of context to identify what the AI model can and cannot do. The seemingly overwhelming number of potential combinations of varied types of context could pose the greatest challenge for AI follow-up questions. For example, human moderators may decide to go against the general rules by asking less open-ended questions to obtain information that is essential for the goals of their research while also understanding the tradeoffs. In our study, we have observed that if the AI asked questions that were too generically open-ended as a follow-up to seed questions that were open-ended themselves, without a significant enough shift in perspective, this resulted in repetition, irrelevancy, and — therefore — frustration. The fine-tuning of the AI models to achieve an ability to resolve various types of contextual conflict appropriately could be seen as a reliable metric by which the quality of the AI generator of follow-up questions could be measured. Researcher control is also key since tougher decisions that are reliant on the researcher’s vision and understanding should remain firmly in the researcher’s hands. Because of this, a combination of static and AI-driven questions with complementary strengths and weaknesses could be the way to unlock richer insights. A focus on contextual sensitivity validation can be seen as even more important while considering the broader social aspects. Among certain people, the trend-chasing and the general overhype of AI by the industry have led to a backlash against AI. AI skeptics have a number of valid concerns, including usefulness, ethics, data privacy, and the environment. Some usability testing participants may be unaccepting or even outwardly hostile toward encounters with AI. Therefore, for the successful incorporation of AI into research, it will be essential to demonstrate it to the users as something that is both reasonable and helpful. Principles of ethical research remain as relevant as ever. Data needs to be collected and processed with the participant’s consent and not breach the participant’s privacy (e.g. so that sensitive data is not used for training AI models without permission). Conclusion: What’s Next For AI In UX? So, is AI a game-changer that could break down the barrier between moderated and unmoderated usability research? Maybe one day. The potential is certainly there. When AI follow-up questions work as intended, the results are exciting. Participants can become more talkative and clarify potentially essential details. To any UX researcher who’s familiar with the feeling of analyzing vaguely phrased feedback and wishing that they could have been there to ask one more question to drive the point home, an automated solution that could do this for them may seem like a dream. However, we should also exercise caution since the blind addition of AI without testing and oversight can introduce a slew of biases. This is because the relevance of follow-up questions is dependent on all sorts of contexts. Humans need to keep holding the reins in order to ensure that the research is based on actual solid conclusions and intents. The opportunity lies in the synergy that can arise from usability researchers and designers whose ability to conduct unmoderated usability testing could be significantly augmented. Humans + AI = Better Insights The best approach to advocate for is likely a balanced one. As UX researchers and designers, humans should continue to learn how to use AI as a partner in uncovering insights. This article can serve as a jumping-off point, providing a list of the AI-driven technique’s potential weak points to be aware of, to monitor, and to improve on.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          How OWASP Helps You Secure Your Full-Stack Web Applications

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            The OWASP vulnerabilities list is the perfect starting point for web developers looking to strengthen their security expertise. Let’s discover how these vulnerabilities materialize in full-stack web applications and how to prevent them.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            Security can be an intimidating topic for web developers. The vocabulary is rich and full of acronyms. Trends evolve quickly as hackers and analysts play a perpetual cat-and-mouse game. Vulnerabilities stem from little details we cannot afford to spend too much time on during our day-to-day operations. JavaScript developers already have a lot to take with the emergence of a new wave of innovative architectures, such as React Server Components, Next.js App Router, or Astro islands. So, let’s have a focused approach. What we need is to be able to detect and palliate the most common security issues. A top ten of the most common vulnerabilities would be ideal. Meet The OWASP Top 10 Guess what: there happens to be such a top ten of the most common vulnerabilities, curated by experts in the field! It is provided by the OWASP Foundation, and it’s an extremely valuable resource for getting started with security. OWASP stands for “Open Worldwide Application Security Project.” It’s a nonprofit foundation whose goal is to make software more secure globally. It supports many open-source projects and produces high-quality education resources, including the OWASP top 10 vulnerabilities list. We will dive through each item of the OWASP top 10 to understand how to recognize these vulnerabilities in a full-stack application. Note: I will use Next.js as an example, but this knowledge applies to any similar full-stack architecture, even outside of the JavaScript ecosystem. Let’s start our countdown towards a safer web! Number 10: Server-Side Request Forgery (SSRF) You may have heard about Server-Side Rendering, aka SSR. Well, you can consider SSRF to be its evil twin acronym. Server-Side Request Forgery can be summed up as letting an attacker fire requests using your backend server. Besides hosting costs that may rise up, the main problem is that the attacker will benefit from your server’s level of accreditation. In a complex architecture, this means being able to target your internal private services using your own corrupted server. Here is an example. Our app lets a user input a URL and summarizes the content of the target page server-side using an AI SDK. A mischievous user passes localhost:3000 as the URL instead of a website they’d like to summarize. Your server will fire a request against itself or any other service running on port 3000 in your backend infrastructure. This is a severe SSRF vulnerability! You’ll want to be careful when firing requests based on user inputs, especially server-side. Number 9: Security Logging And Monitoring Failures I wish we could establish a telepathic connection with our beloved Node.js server running in the backend. Instead, the best thing we have to see what happens in the cloud is a dreadful stream of unstructured pieces of text we name “logs.” Yet we will have to deal with that, not only for debugging or performance optimization but also because logs are often the only information you’ll get to discover and remediate a security issue. As a starter, you might want to focus on logging the most important transactions of your application exactly like you would prioritize writing end-to-end tests. In most applications, this means login, signup, payouts, mail sending, and so on. In a bigger company, a more complete telemetry solution is a must-have, such as Open Telemetry, Sentry, or Datadog. If you are using React Server Components, you may need to set up a proper logging strategy anyway since it’s not possible to debug them directly from the browser as we used to do for Client components. Number 8: Software And Data Integrity Failures The OWASP top 10 vulnerabilities tend to have various levels of granularity, and this one is really a big family. I’d like to focus on supply chain attacks, as they have gained a lot of popularity over the years. You may have heard about the Log4J vulnerability. It was very publicized, very critical, and very exploited by hackers. It’s a massive supply chain attack. In the JavaScript ecosystem, you most probably install your dependencies using NPM. Before picking dependencies, you might want to craft yourself a small list of health indicators. Is the library maintained and tested with proper code? Does it play a critical role in my application? Who is the main contributor? Did I spell it right when installing? For more serious business, you might want to consider setting up a Supply Chain Analysis (SCA) solution; GitHub’s Dependabot is a free one, and Snyk and Datadog are other famous actors. Number 7: Identification And Authentication Failures Here is a stereotypical vulnerability belonging to this category: your admin password is leaked. A hacker finds it. Boom, game over. Password management procedures are beyond the scope of this article, but in the context of full-stack web development, let’s dive deep into how we can prevent brute force attacks using Next.js edge middlewares. Middlewares are tiny proxies written in JavaScript. They process requests in a way that is supposed to be very, very fast, faster than a normal Node.js endpoint, for example. They are a good fit for handling low-level processing, like blocking malicious IPs or redirecting users towards the correct translation of a page. One interesting use case is rate limiting. You can quickly improve the security of your applications by limiting people’s ability to spam your POST endpoints, especially login and signup. You may go even further by setting up a Web Applications Firewall (WAF). A WAF lets developers implement elaborate security rules. This is not something you would set up directly in your application but rather at the host level. For instance, Vercel has released its own WAF in 2024. Number 6: Vulnerable And Outdated Components We have discussed supply chain attacks earlier. Outdated components are a variation of this vulnerability, where you actually are the person to blame. Sorry about that. Security vulnerabilities are often discovered ahead of time by diligent security analysts before a mean attacker can even start thinking about exploiting them. Thanks, analysts friends! When this happens, they fill out a Common Vulnerabilities and Exposure and store that in a public database. The remedy is the same as for supply chain attacks: set up an SCA solution like Dependabot that will regularly check for the use of vulnerable packages in your application. Halfway break I just want to mention at this point how much progress we have made since the beginning of this article. To sum it up: We know how to recognize an SSRF. This is a nasty vulnerability, and it is easy to accidentally introduce while crafting a super cool feature. We have identified monitoring and dependency analysis solutions as important pieces of “support” software for securing applications. We have figured out a good use case for Next.js edge middlewares: rate limiting our authentication endpoints to prevent brute force attacks. It’s a good time to go grab a tea or coffee. But after that, come back with us because we are going to discover the five most common vulnerabilities affecting web applications! Number 5: Security Misconfiguration There are so many configurations that we can mismanage. But let’s focus on the most insightful ones for a web developer learning about security: HTTP headers. You can use HTTP response headers to pass on a lot of information to the user’s browser about what’s possible or not on your website. For example, by narrowing down the “Permissions-Policy” headers, you can claim that your website will never require access to the user’s camera. This is an extremely powerful protection mechanism in case of a script injection attack (XSS). Even if the hacker manages to run a malicious script in the victim’s browser, the latter will not allow the script to access the camera. I invite you to observe the security configuration of any template or boilerplate that you use to craft your own websites. Do you understand them properly? Can you improve them? Answering these questions will inevitably lead you to vastly increase the safety of your websites! Number 4: Insecure Design I find this one funny, although a bit insulting for us developers. Bad code is literally the fourth most common cause of vulnerabilities in web applications! You can’t just blame your infrastructure team anymore. Design is actually not just about code but about the way we use our programming tools to produce software artifacts. In the context of full-stack JavaScript frameworks, I would recommend learning how to use them idiomatically, the same way you’d want to learn a foreign language. It’s not just about translating what you already know word-by-word. You need to get a grasp of how a native speaker would phrase their thoughts. Learning idiomatic Next.js is really, really hard. Trust me, I teach this framework to web developers. Next is all about client and server logic hybridization, and some patterns may not even transfer to competing frameworks with a different architecture like Astro.js or Remix. Hopefully, the Next.js core team has produced many free learning resources, including articles and documentation specifically focusing on security. I recommend reading Sebastian Markbåge’s famous article “How to Think About Security in Next.js” as a starting point. If you use Next.js in a professional setting, consider organizing proper training sessions before you start working on high-stakes projects. Number 3: Injection Injections are the epitome of vulnerabilities, the quintessence of breaches, and the paragon of security issues. SQL injections are typically very famous, but JavaScript injections are also quite common. Despite being well-known vulnerabilities, injections are still in the top 3 in the OWASP ranking! Injections are the reason why forcing a React component to render HTML is done through an unwelcoming dangerouslySetInnerHTML function. React doesn’t want you to include user input that could contain a malicious script. The screenshot below is a demonstration of an injection using images. It could target a message board, for instance. The attacker misused the image posting system. They passed a URL that points towards an API GET endpoint instead of an actual image. Whenever your website’s users see this post in their browser, an authenticated request is fired against your backend, triggering a payment! As a bonus, having a GET endpoint that triggers side-effects such as payment also constitutes a risk of Cross-Site Request Forgery (CSRF, which happens to be SSRF client-side cousin). Even experienced developers can be caught off-guard. Are you aware that dynamic route parameters are user inputs? For instance, [language]/page.jsx in a Next.js or Astro app. I often see clumsy attack attempts when logging them, like “language” being replaced by a path traversal like ../../../../passwords.txt. Zod is a very popular library for running server-side data validation of user inputs. You can add a transform step to sanitize inputs included in database queries, or that could land in places where they end up being executed as code. Number 2: Cryptographic Failures A typical discussion between two developers that are in deep, deep trouble: — We have leaked our database and encryption key. What algorithm was used to encrypt the password again? AES-128 or SHA-512? — I don’t know, aren’t they the same thing? They transform passwords into gibberish, right? — Alright. We are in deep, deep trouble. This vulnerability mostly concerns backend developers who have to deal with sensitive personal identifiers (PII) or passwords. To be honest, I don’t know much about these algorithms; I studied computer science way too long ago. The only thing I remember is that you need non-reversible algorithms to encrypt passwords, aka hashing algorithms. The point is that if the encrypted passwords are leaked, and the encryption key is also leaked, it will still be super hard to hack an account (you can’t just reverse the encryption). In the State of JavaScript survey, we use passwordless authentication with an email magic link and one-way hash emails, so even as admins, we cannot guess a user’s email in our database. And number 1 is... Such suspense! We are about to discover that the top 1 vulnerability in the world of web development is... Broken Access Control! Tada. Yeah, the name is not super insightful, so let me rephrase it. It’s about people being able to access other people’s accounts or people being able to access resources they are not allowed to. That’s more impressive when put this way. A while ago, I wrote an article about the fact that checking authorization within a layout may leave page content unprotected in Next.js. It’s not a flaw in the framework’s design but a consequence of how React Server Components have a different model than their client counterparts, which then affects how the layout works in Next. Here is a demo of how you can implement a paywall in Next.js that doesn’t protect anything. // app/layout.jsx // Using cookie-based authentication as usual async function checkPaid() { const token = cookies.get("auth_token"); return await db.hasPayments(token); } // Running the payment check in a layout to apply it to all pages // Sadly, this is not how Next.js works! export default async function Layout() { // ❌ this won't work as expected!! const hasPaid = await checkPaid(); if (!hasPaid) redirect("/subscribe"); // then render the underlying page return <div>{children}</div>; } // ❌ this can be accessed directly // by adding “RSC=1” to the request that fetches it! export default function Page() { return <div>PAID CONTENT</div> } What We Have Learned From The Top 5 Vulnerabilities Most common vulnerabilities are tightly related to application design issues: Copy-pasting configuration without really understanding it. Having an improper understanding of the framework we use in inner working. Next.js is a complex beast and doesn’t make our life easier on this point! Picking an algorithm that is not suited for a given task. These vulnerabilities are tough ones because they confront us to our own limits as web developers. Nobody is perfect, and the most experienced developers will inevitably write vulnerable code at some point in their lives without even noticing. How to prevent that? By not staying alone! When in doubt, ask around fellow developers; there are great chances that someone has faced the same issues and can lead you to the right solutions. Where To Head Now? First, I must insist that you have already done a great job of improving the security of your applications by reading this article. Congratulations! Most hackers rely on a volume strategy and are not particularly skilled, so they are really in pain when confronted with educated developers who can spot and fix the most common vulnerabilities. From there, I can suggest a few directions to get even better at securing your web applications: Try to apply the OWASP top 10 to an application you know well, either a personal project, your company’s codebase, or an open-source solution. Give a shot at some third-party security tools. They tend to overflow developers with too much information but keep in mind that most actors in the field of security are aware of this issue and work actively to provide more focused vulnerability alerts. I’ve added my favorite security-related resources at the end of the article, so you’ll have plenty to read! Thanks for reading, and stay secure! Resources For Further Learning An interactive demo of an SSRF in a Next.js app and how to fix it OWASP Top 10 An SSRF vulnerability that affected Next.js image optimization system Observe React Server Components using Open Telemetry OpenTelemetry and open source Telemtry standard Log4J vulnerability Setting up rate limiting in a middleware using a Redis service Vercel WAF annoucement Mitre CVE database An interactive demo of a CSRF vulnerability in a Next.js app and how to fix it A super complete guide on authentication specifically targeting web apps Server form validation with zod in Next.js (Astro has it built-in) Sanitization with zod Secure statically rendered paid content in Next.js and how layouts are a bad place to run authentication checks Smashing Magazine articles related to security (almost 50 matches at the time of writing!) This article is inspired by my talk at React Advanced London 2024, “Securing Server-Rendered Applications: Next.js case,” which is available to watch as a replay online.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            How To Test And Measure Content In UX

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              The goal of content design is to reduce confusion and improve clarity. Yet often it’s difficult to pinpoint a problem as user feedback tends to be not specific enough. But: we can use a few simple techniques to assess how users understand and perceive content. Let’s take a look. Part of [How To Measure UX & Design Impact](https://measure-ux.com/) by yours truly.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              Content testing is a simple way to test the clarity and understanding of the content on a page — be it a paragraph of text, a user flow, a dashboard, or anything in between. Our goal is to understand how well users actually perceive the content that we present to them. It’s not only about finding pain points and things that cause confusion or hinder users from finding the right answer on a page but also about if our content clearly and precisely articulates what we actually want to communicate. This article is part of our ongoing series on UX. You can find more details on design patterns and UX strategy in Smart Interface Design Patterns 🍣 — with live UX training coming up soon. Free preview. Banana Testing A great way to test how well your design matches a user’s mental model is Banana Testing. We replace all key actions with the word “Banana,” then ask users to suggest what each action could prompt. Not only does it tell you if key actions are understood immediately and if they are in the right place but also if your icons are helpful and if interactive elements such as links or buttons are perceived as such. Content Heatmapping One reliable technique to assess content is content heatmapping. The way we would use it is by giving participants a task, then asking them to highlight things that are clear or confusing. We could define any other dimensions or style lenses as well: e.g., phrases that bring more confidence and less confidence. Then we map all highlights into a heatmap to identify patterns and trends. You could run it with print-outs in person, but it could also happen in Figjam or in Miro remotely — as long as your tool of choice has a highlighter feature. Run Moderated Testing Sessions These little techniques above help you discover content issues, but they don’t tell you what is missing in the content and what doubts, concerns, and issues users have with it. For that, we need to uncover user needs in more detail. Too often, users say that a page is “clear and well-organized,” but when you ask them specific questions, you notice that their understanding is vastly different from what you were trying to bring into spotlight. Such insights rarely surface in unmoderated sessions — it’s much more effective to observe behavior and ask questions on the spot, be it in person or remote. Test Concepts, Not Words Before testing, we need to know what we want to learn. First, write up a plan with goals, customers, questions, script. Don’t tweak words alone — broader is better. In the session, avoid speaking aloud as it’s usually not how people consume content. Ask questions and wait silently. After the task is completed, ask users to explain the product, flow, and concepts to you. But: don’t ask them what they like, prefer, feel, or think. And whenever possible, avoid the word “content” in testing as users often perceive it differently. Choosing The Right Way To Test There are plenty of different tests that you could use: Banana test 🍌 Replace key actions with “bananas,” ask to explain. Cloze test 🕳️ Remove words from your copy, ask users to fill in the blanks. Reaction cards 🤔 Write up emotions on 25 cards, ask users to choose. Card sorting 🃏 Ask users to group topics into meaningful categories. Highlighting 🖍️ Ask users to highlight helpful or confusing words. Competitive testing 🥊 Ask users to explain competitors’ pages. When choosing the right way to test, consider the following guidelines: Do users understand? Interviews, highlighting, Cloze test Do we match the mental model? Banana testing, Cloze test What word works best? Card sorting, A/B testing, tree testing Why doesn’t it work? Interviews, highlighting, walkthroughs Do we know user needs? Competitive testing, process mapping Wrapping Up In many tasks, there is rarely anything more impactful than the careful selection of words on a page. However, it’s not only the words alone that are being used but the voice and tone that you choose to communicate with customers. Use the techniques above to test and measure how well people perceive content but also check how they perceive the end-to-end experience on the site. Quite often, the right words used incorrectly on a key page can convey a wrong message or provide a suboptimal experience. Even though the rest of the product might perform remarkably well, if a user is blocked on a critical page, they will be gone before you even blink. Useful Resources Practical Guide To Content Testing, by Intuit How To Test Content With Users, by Kate Moran Five Fun Ways To Test Words, by John Saito A Simple Technique For Evaluating Content, by Pete Gale New: How To Measure UX And Design Impact Meet Measure UX & Design Impact (8h), a new practical guide for designers and UX leads to measure and show your UX impact on business. Use the code 🎟 IMPACT to save 20% off today. Jump to the details. Video + UX Training Video only Video + UX Training $ 495.00 $ 799.00 Get Video + UX Training 25 video lessons (8h) + Live UX Training. 100 days money-back-guarantee. Video only $ 250.00$ 395.00 Get the video course 25 video lessons (8h). Updated yearly. Also available as a UX Bundle with 2 video courses.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              Time To First Byte: Beyond Server Response Time

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                Optimizing web performance means looking beyond surface-level metrics. Time to First Byte (TTFB) is crucial, but improving it requires more than tweaking server response time. Matt Zeunert breaks down what TTFB is, what causes its poor score, and why reducing server response time alone isn’t enough for optimization and often won’t be the most impactful change you can make to your website.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                This article is a sponsored by DebugBear Loading your website HTML quickly has a big impact on visitor experience. After all, no page content can be displayed until after the first chunk of the HTML has been loaded. That’s why the Time to First Byte (TTFB) metric is important: it measures how soon after navigation the browser starts receiving the HTML response. Generating the HTML document quickly plays a big part in minimizing TTFB delays. But actually, there’s a lot more to optimizing this metric. In this article, we’ll take a look at what else can cause poor TTFB and what you can do to fix it. What Components Make Up The Time To First Byte Metric? TTFB stands for Time to First Byte. But where does it measure from? Different tools handle this differently. Some only count the time spent sending the HTTP request and getting a response, ignoring everything else that needs to happen first before the resource can be loaded. However, when looking at Google’s Core Web Vitals, TTFB starts from the time when the users start navigating to a new page. That means TTFB includes: Cross-origin redirects, Time spent connecting to the server, Same-origin redirects, and The actual request for the HTML document. We can see an example of this in this request waterfall visualization. The server response time here is only 183 milliseconds, or about 12% of the overall TTFB metric. Half of the time is instead spent on a cross-origin redirect — a separate HTTP request that returns a redirect response before we can even make the request that returns the website’s HTML code. And when we make that request, most of the time is spent on establishing the server connection. Connecting to a server on the web typically takes three round trips on the network: DNS: Looking up the server IP address. TCP: Establishing a reliable connection to the server. TLS: Creating a secure encrypted connection. What Network Latency Means For Time To First Byte Let’s add up all the network round trips in the example above: 2 server connections: 6 round trips. 2 HTTP requests: 2 round trips. That means that before we even get the first response byte for our page we actually have to send data back and forth between the browser and a server eight times! That’s where network latency comes in, or network round trip time (RTT) if we look at the time it takes to send data to a server and receive a response in the browser. On a high-latency connection with a 150 millisecond RTT, making those eight round trips will take 1.2 seconds. So, even if the server always responds instantly, we can’t get a TTFB lower than that number. Network latency depends a lot on the geographic distances between the visitor’s device and the server the browser is connecting to. You can see the impact of that in practice by running a global TTFB test on a website. Here, I’ve tested a website that’s hosted in Brazil. We get good TTFB scores when testing from Brazil and the US East Coast. However, visitors from Europe, Asia, or Australia wait a while for the website to load. What Content Delivery Networks Mean for Time to First Byte One way to speed up your website is by using a Content Delivery Network (CDN). These services provide a network of globally distributed server locations. Instead of each round trip going all the way to where your web application is hosted, browsers instead connect to a nearby CDN server (called an edge node). That greatly reduces the time spent on establishing the server connection, improving your overall TTFB metric. By default, the actual HTML request still has to be sent to your web app. However, if your content isn’t dynamic, you can also cache responses at the CDN edge node. That way, the request can be served entirely through the CDN instead of data traveling all across the world. If we run a TTFB test on a website that uses a CDN, we can see that each server response comes from a regional data center close to where the request was made. In many cases, we get a TTFB of under 200 milliseconds, thanks to the response already being cached at the edge node. How To Improve Time To First Byte What you need to do to improve your website’s TTFB score depends on what its biggest contributing component is. A lot of time is spent establishing the connection: Use a global CDN. The server response is slow: Optimize your application code or cache the response Redirects delay TTFB: Avoid chaining redirects and optimize the server returning the redirect response. Keep in mind that TTFB depends on how visitors are accessing your website. For example, if they are logged into your application, the page content probably can’t be served from the cache. You may also see a spike in TTFB when running an ad campaign, as visitors are redirected through a click-tracking server. Monitor Real User Time To First Byte If you want to get a breakdown of what TTFB looks like for different visitors on your website, you need real user monitoring. That way, you can break down how visitor location, login status, or the referrer domain impact real user experience. DebugBear can help you collect real user metrics for Time to First Byte, Google Core Web Vitals, and other page speed metrics. You can track individual TTFB components like TCP duration or redirect time and break down website performance by country, ad campaign, and more. Conclusion By looking at everything that’s involved in serving the first byte of a website to a visitor, we’ve seen that just reducing server response time isn’t enough and often won’t even be the most impactful change you can make on your website. Just because your website is fast in one location doesn’t mean it’s fast for everyone, as website speed varies based on where the visitor is accessing your site from. Content Delivery Networks are an incredibly powerful way to improve TTFB. Even if you don’t use any of their advanced features, just using their global server network saves a lot of time when establishing a server connection.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                Taking RWD To The Extreme

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  Tomasz Jakut reflects on the evolution of web design, from the days of table-based layouts and Flash games to the rise of responsive web design (RWD), which often feels like the end of history in web layout. But as 2025 marks the 15th anniversary of Ethan Marcotte’s article, it’s worth asking whether something significant happened after RWD — something so seamless that it went almost unnoticed.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  When Ethan Marcotte conceived RWD, web technologies were far less mature than today. As web developers, we started to grasp how to do things with floats after years of stuffing everything inside table cells. There weren’t many possible ways to achieve a responsive site. There were two of them: fluid grids (based on percentages) and media queries, which were a hot new thing back then. What was lacking was a real layout system that would allow us to lay things out on a page instead of improvising with floating content. We had to wait several years for Flexbox to appear. And CSS Grid followed that. Undoubtedly, new layout systems native to the browser were groundbreaking 10 years ago. They were revolutionary enough to usher in a new era. In her talk “Everything You Know About Web Design Just Changed” at the An Event Apart conference in 2019, Jen Simmons proposed a name for it: Intrinsic Web Design (IWD). Let’s disarm that fancy word first. According to the Merriam-Webster dictionary, intrinsic means “belonging to the essential nature or constitution of a thing.” In other words, IWD is a natural way of doing design for the web. And that boils down to using CSS layout systems for… laying out things. That’s it. It does not sound that groundbreaking on its own. But it opens a lot of possibilities that weren’t earlier available with float-based layouts or table ones. We got the best things from both worlds: two-dimensional layouts (like tables with their rows and columns) with wrapping abilities (like floating content when there is not enough space for it). And there are even more goodies, like mixing fixed-sized content with fluid-sized content or intentionally overlapping elements: Native layout systems are here to make the browser work for you — don’t hesitate to use that to your advantage. Start With Semantic HTML HTML is the backbone of the web. It’s the language that structures and formats the content for the user. And it comes with a huge bonus: it loads and displays to the user, even if CSS and JavsScript fail to load for whatever reason. In other words, the website should still make sense to the user even if the CSS that provides the layout and the JavsScript that provides the interactivity are no-shows. A website is a text document, not so different from the one you can create in a text processor, like Word or LibreWriter. Semantic HTML also provides important accessibility features, like headings that are often used by screen-reader users for navigating pages. This is why starting not just with any markup but semantic markup for meaningful structure is a crucial step to embracing native web features. Use Fluid Type With Fluid Space We often need to adjust the font size of our content when the screen size changes. Smaller screens mean being able to display less content, and larger screens provide more affordance for additional content. This is why we ought to make content as fluid as possible, by which I mean the content should automatically adjust based on the screen’s size. A fluid typographic system optimizes the content’s legibility when it’s being viewed in different contexts. Nowadays, we can achieve truly fluid type with one line of CSS, thanks to the clamp() function: font-size: clamp(1rem, calc(1rem + 2.5vw), 6rem); The maths involved in it goes quite above my head. Thankfully, there is a detailed article on fluid type by Adrian Bece here on Smashing Magazine and Utopia, a handy tool for doing the maths for us. But beware — there be dragons! Or at least possible accessibility issues. By limiting the maximum font size, we could break the ability to zoom the text content, violating one of the WCAG’s requirements (though there are ways to address that). Fortunately, fluid space is much easier to grasp: if gaps (margins) between elements are defined in font-dependent units (like rem or em), they will scale alongside the font size. Yet rest assured, there are also caveats. Always Bet On Progressive Enhancement Yes, that’s this over-20-year-old technique for creating web pages. And it’s still relevant today in 2025. Many interesting features have limited availability — like cross-page view transitions. They won’t work for every user, but enabling them is as simple as adding one line of CSS: @view-transition { navigation: auto; } It won’t work in some browsers, but it also won’t break anything. And if some browser catches up with the standard, the code is already there, and view transitions start to work in that browser on your website. It’s sort of like opting into the feature when it’s ready. That’s progressive enhancement at its best: allowing you to make your stairs into an escalator whenever it’s possible. It applies to many more things in CSS (unsupported grid is just a flow layout, unsupported masonry layout is just a grid, and so on) and other web technologies. Trust The Browser Trust it because it knows much more about how safe it is for users to surf the web. Besides, it’s a computer program, and computer programs are pretty good at calculating things. So instead of calculating all these breakpoints ourselves, take their helping hand and allow them to do it for you. Just give them some constraints. Make that <main> element no wider than 60 characters and no narrower than 20 characters — and then relax, watching the browser make it 37 characters on some super rare viewport you’ve never encountered before. It Just Works™. But trusting the browser also means trusting the open web. After all, these algorithms responsible for laying things out are all parts of the standards. Ditch The “Physical” CSS That’s a bonus point from me. Layout systems introduced the concept of logical CSS. Flexbox does not have a notion of a left or right side — it has a start and an end. And that way of thinking lurked into other areas of CSS, creating the whole CSS Logical Properties and Values module. After working more with layout systems, logical CSS seems much more intuitive than the old “physical” one. It also has at least one advantage over the old way of doing things: it works far better with internationalized content. And I know that sounds crazy, but it forces a change in thinking about websites. If you don’t know the most basic information about your content (the font size), you can’t really apply any concrete numbers to your layout. You can only think in ratios. If the font size equals ✕, your heading could equal 2✕, the main column 60✕, some text input — 10✕, and so on. This way, everything should work out with any font size and, by extension, scale up with any font size. We’ve already been doing that with layout systems — we allow them to work on ratios and figure out how big each part of the layout should be. And we’ve also been doing that with rem and em units for scaling things up depending on font size. The only thing left is to completely forget the “1rem = 16px” equation and fully embrace the exciting shores of unknown dimensions. But that sort of mental shift comes with one not-so-straightforward consequence. Not setting the font size and working with the user-provided one instead fully moves the power from the web developer to the browser and, effectively, the user. And the browser can provide us with far more information about user preferences. Thanks to the modern CSS, we can respond to these things. For example, we can switch to dark mode if the user prefers one, we can limit motion if the user requests it, we can make clickable areas bigger if the device has a touch screen, and so on. By having this kind of dialogue with the browser, exchanging information (it gives us data on the user, and we give it hints on how to display our content), we empower the user in the result. The content would be displayed in the way they want. That makes our website far more inclusive and accessible. After all, the users know what they need best. If they set the default font size to 64 pixels, they would be grateful if we respected that value. We don’t know why they did it (maybe they have some kind of vision impairment, or maybe they simply have a screen far away from them); we only know they did it — and we respect that. And that’s responsive design for me.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  Integrations: From Simple Data Transfer To Modern Composable Architectures

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    In today’s web development landscape, the concept of a monolithic application has become increasingly rare. Modern applications are composed of multiple specialized services, each of which handles specific aspects of functionality. This shift didn’t happen overnight - it’s the result of decades of evolution in how we think about and implement data transfer between systems. Let’s explore this journey and see how it shapes modern architectures, particularly in the context of headless CMS solutions.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    This article is a sponsored by Storyblok When computers first started talking to each other, the methods were remarkably simple. In the early days of the Internet, systems exchanged files via FTP or communicated via raw TCP/IP sockets. This direct approach worked well for simple use cases but quickly showed its limitations as applications grew more complex. # Basic socket server example import socket server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM) server_socket.bind(('localhost', 12345)) server_socket.listen(1) while True: connection, address = server_socket.accept() data = connection.recv(1024) # Process data connection.send(response) The real breakthrough in enabling complex communication between computers on a network came with the introduction of Remote Procedure Calls (RPC) in the 1980s. RPC allowed developers to call procedures on remote systems as if they were local functions, abstracting away the complexity of network communication. This pattern laid the foundation for many of the modern integration approaches we use today. At its core, RPC implements a client-server model where the client prepares and serializes a procedure call with parameters, sends the message to a remote server, the server deserializes and executes the procedure, and then sends the response back to the client. Here’s a simplified example using Python’s XML-RPC. # Server from xmlrpc.server import SimpleXMLRPCServer def calculate_total(items): return sum(items) server = SimpleXMLRPCServer(("localhost", 8000)) server.register_function(calculate_total) server.serve_forever() # Client import xmlrpc.client proxy = xmlrpc.client.ServerProxy("http://localhost:8000/") try: result = proxy.calculate_total([1, 2, 3, 4, 5]) except ConnectionError: print("Network error occurred") RPC can operate in both synchronous (blocking) and asynchronous modes. Modern implementations such as gRPC support streaming and bi-directional communication. In the example below, we define a gRPC service called Calculator with two RPC methods, Calculate, which takes a Numbers message and returns a Result message, and CalculateStream, which sends a stream of Result messages in response. // protobuf service Calculator { rpc Calculate(Numbers) returns (Result); rpc CalculateStream(Numbers) returns (stream Result); } Modern Integrations: The Rise Of Web Services And SOA The late 1990s and early 2000s saw the emergence of Web Services and Service-Oriented Architecture (SOA). SOAP (Simple Object Access Protocol) became the standard for enterprise integration, introducing a more structured approach to system communication. <?xml version="1.0"?> <soap:Envelope xmlns:soap="http://www.w3.org/2003/05/soap-envelope"> <soap:Header> </soap:Header> <soap:Body> <m:GetStockPrice xmlns:m="http://www.example.org/stock"> <m:StockName>IBM</m:StockName> </m:GetStockPrice> </soap:Body> </soap:Envelope> While SOAP provided robust enterprise features, its complexity, and verbosity led to the development of simpler alternatives, especially the REST APIs that dominate Web services communication today. But REST is not alone. Let’s have a look at some modern integration patterns. RESTful APIs REST (Representational State Transfer) has become the de facto standard for Web APIs, providing a simple, stateless approach to manipulating resources. Its simplicity and HTTP-based nature make it ideal for web applications. First defined by Roy Fielding in 2000 as an architectural style on top of the Web’s standard protocols, its constraints align perfectly with the goals of the modern Web, such as performance, scalability, reliability, and visibility: client and server separated by an interface and loosely coupled, stateless communication, cacheable responses. In modern applications, the most common implementations of the REST protocol are based on the JSON format, which is used to encode messages for requests and responses. // Request async function fetchUserData() { const response = await fetch('https://api.example.com/users/123'); const userData = await response.json(); return userData; } // Response { "id": "123", "name": "John Doe", "_links": { "self": { "href": "/users/123" }, "orders": { "href": "/users/123/orders" }, "preferences": { "href": "/users/123/preferences" } } } GraphQL GraphQL emerged from Facebook’s internal development needs in 2012 before being open-sourced in 2015. Born out of the challenges of building complex mobile applications, it addressed limitations in traditional REST APIs, particularly the issues of over-fetching and under-fetching data. At its core, GraphQL is a query language and runtime that provides a type system and declarative data fetching, allowing the client to specify exactly what it wants to fetch from the server. // graphql type User { id: ID! name: String! email: String! posts: [Post!]! } type Post { id: ID! title: String! content: String! author: User! publishDate: String! } query GetUserWithPosts { user(id: "123") { name posts(last: 3) { title publishDate } } } Often used to build complex UIs with nested data structures, mobile applications, or microservices architectures, it has proven effective at handling complex data requirements at scale and offers a growing ecosystem of tools. Webhooks Modern applications often require real-time updates. For example, e-commerce apps need to update inventory levels when a purchase is made, or content management apps need to refresh cached content when a document is edited. Traditional request-response models can struggle to meet these demands because they rely on clients’ polling servers for updates, which is inefficient and resource-intensive. Webhooks and event-driven architectures address these needs more effectively. Webhooks let servers send real-time notifications to clients or other systems when specific events happen. This reduces the need for continuous polling. Event-driven architectures go further by decoupling application components. Services can publish and subscribe to events asynchronously, and this makes the system more scalable, responsive, and simpler. import fastify from 'fastify'; const server = fastify(); server.post('/webhook', async (request, reply) => { const event = request.body; if (event.type === 'content.published') { await refreshCache(); } return reply.code(200).send(); }); This is a simple Node.js function that uses Fastify to set up a web server. It responds to the endpoint /webhook, checks the type field of the JSON request, and refreshes a cache if the event is of type content.published. With all this background information and technical knowledge, it’s easier to picture the current state of web application development, where a single, monolithic app is no longer the answer to business needs, but a new paradigm has emerged: Composable Architecture. Composable Architecture And Headless CMSs This evolution has led us to the concept of composable architecture, where applications are built by combining specialized services. This is where headless CMS solutions have a clear advantage, serving as the perfect example of how modern integration patterns come together. Headless CMS platforms separate content management from content presentation, allowing you to build specialized frontends relying on a fully-featured content backend. This decoupling facilitates content reuse, independent scaling, and the flexibility to use a dedicated technology or service for each part of the system. Take Storyblok as an example. Storyblok is a headless CMS designed to help developers build flexible, scalable, and composable applications. Content is exposed via API, REST, or GraphQL; it offers a long list of events that can trigger a webhook. Editors are happy with a great Visual Editor, where they can see changes in real time, and many integrations are available out-of-the-box via a marketplace. Imagine this ContentDeliveryService in your app, where you can interact with Storyblok’s REST API using the open source JS Client: import StoryblokClient from "storyblok-js-client"; class ContentDeliveryService { constructor(private storyblok: StoryblokClient) {} async getPageContent(slug: string) { const { data } = await this.storyblok.get(cdn/stories/${slug}, { version: 'published', resolve_relations: 'featured-products.products' }); return data.story; } async getRelatedContent(tags: string[]) { const { data } = await this.storyblok.get('cdn/stories', { version: 'published', with_tag: tags.join(',') }); return data.stories; } } The last piece of the puzzle is a real example of integration. Again, many are already available in the Storyblok marketplace, and you can easily control them from the dashboard. However, to fully leverage the Composable Architecture, we can use the most powerful tool in the developer’s hand: code. Let’s imagine a modern e-commerce platform that uses Storyblok as its content hub, Shopify for inventory and orders, Algolia for product search, and Stripe for payments. Once each account is set up and we have our access tokens, we could quickly build a front-end page for our store. This isn’t production-ready code, but just to get a quick idea, let’s use React to build the page for a single product that integrates our services. First, we should initialize our clients: import StoryblokClient from "storyblok-js-client"; import { algoliasearch } from "algoliasearch"; import Client from "shopify-buy"; const storyblok = new StoryblokClient({ accessToken: "your_storyblok_token", }); const algoliaClient = algoliasearch( "your_algolia_app_id", "your_algolia_api_key", ); const shopifyClient = Client.buildClient({ domain: "your-shopify-store.myshopify.com", storefrontAccessToken: "your_storefront_access_token", }); Given that we created a blok in Storyblok that holds product information such as the product_id, we could write a component that takes the productSlug, fetches the product content from Storyblok, the inventory data from Shopify, and some related products from the Algolia index: async function fetchProduct() { // get product from Storyblok const { data } = await storyblok.get(cdn/stories/${productSlug}); // fetch inventory from Shopify const shopifyInventory = await shopifyClient.product.fetch( data.story.content.product_id ); // fetch related products using Algolia const { hits } = await algoliaIndex.search("products", { filters: category:${data.story.content.category}, }); } We could then set a simple component state: const [productData, setProductData] = useState(null); const [inventory, setInventory] = useState(null); const [relatedProducts, setRelatedProducts] = useState([]); useEffect(() => // ... // combine fetchProduct() with setState to update the state // ... fetchProduct(); }, [productSlug]); And return a template with all our data: <h1>{productData.content.title}</h1> <p>{productData.content.description}</p> <h2>Price: ${inventory.variants[0].price}</h2> <h3>Related Products</h3> <ul> {relatedProducts.map((product) => ( <li key={product.objectID}>{product.name}</li> ))} </ul> We could then use an event-driven approach and create a server that listens to our shop events and processes the checkout with Stripe (credits to Manuel Spigolon for this tutorial): const stripe = require('stripe') module.exports = async function plugin (app, opts) { const stripeClient = stripe(app.config.STRIPE_PRIVATE_KEY) server.post('/create-checkout-session', async (request, reply) => { const session = await stripeClient.checkout.sessions.create({ line_items: [...], // from request.body mode: 'payment', success_url: "https://your-site.com/success", cancel_url: "https://your-site.com/cancel", }) return reply.redirect(303, session.url) }) // ... And with this approach, each service is independent of the others, which helps us achieve our business goals (performance, scalability, flexibility) with a good developer experience and a smaller and simpler application that’s easier to maintain. Conclusion The integration between headless CMSs and modern web services represents the current and future state of high-performance web applications. By using specialized, decoupled services, developers can focus on business logic and user experience. A composable ecosystem is not only modular but also resilient to the evolving needs of the modern enterprise. These integrations highlight the importance of mastering API-driven architectures and understanding how different tools can harmoniously fit into a larger tech stack. In today’s digital landscape, success lies in choosing tools that offer flexibility and efficiency, adapt to evolving demands, and create applications that are future-proof against the challenges of tomorrow. If you want to dive deeper into the integrations you can build with Storyblok and other services, check out Storyblok’s integrations page. You can also take your projects further by creating your own plugins with Storyblok’s plugin development resources.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    Look Closer, Inspiration Lies Everywhere (February 2025 Wallpapers Edition)

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      Let’s make the most of the shortest of all months, with a new collection of desktop wallpapers celebrating new opportunities, sweet memories, happy little moments, and everything in between. All of them created with love by the community for the community. Enjoy!

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      As designers, we are always on the lookout for some fresh inspiration, and well, sometimes, the best inspiration lies right in front of us. With that in mind, we embarked on our wallpapers adventure more than thirteen years ago. The idea: to provide you with a new batch of beautiful and inspiring desktop wallpapers every month. This February is no exception, of course. The wallpapers in this post were designed by artists and designers from across the globe and come in versions with and without a calendar for February 2025. And since so many unique wallpaper designs have seen the light of day since we first started this monthly series, we also added some February “oldies but goodies” from our archives to the collection — so maybe you’ll spot one of your almost-forgotten favorites in here, too? This wallpapers post wouldn’t have been possible without the kind support of our wonderful community who tickles their creativity each month anew to keep the steady stream of wallpapers flowing. So, a huge thank-you to everyone who shared their designs with us this time around! If you too would like to get featured in one of our next wallpapers posts, please don’t hesitate to submit your design. We can’t wait to see what you’ll come up with! Happy February! You can click on every image to see a larger preview. We respect and carefully consider the ideas and motivation behind each and every artist’s work. This is why we give all artists the full freedom to explore their creativity and express emotions and experience through their works. This is also why the themes of the wallpapers weren’t anyhow influenced by us but rather designed from scratch by the artists themselves. Submit your wallpaper design! 👩‍🎨 Feeling inspired? We are always looking for creative talent and would love to feature your desktop wallpaper in one of our upcoming posts. Join in ↬ Fall In Love With Yourself “We dedicate February to Frida Kahlo to illuminate the world with color. Fall in love with yourself, with life and then with whoever you want.” — Designed by Veronica Valenzuela from Spain. preview with calendar: 640x480, 800x480, 1024x768, 1280x720, 1280x800, 1440x900, 1600x1200, 1920x1080, 1920x1440, 2560x1440 without calendar: 640x480, 800x480, 1024x768, 1280x720, 1280x800, 1440x900, 1600x1200, 1920x1080, 1920x1440, 2560x1440 Sweet Valentine “Everyone deserves a sweet Valentine’s Day, no matter their relationship status. It’s a day to celebrate love in all its forms — self-love, friendship, and the love we share with others. A little kindness or just a little chocolate can make anyone feel special, reminding us that everyone is worthy of love and joy.” — Designed by LibraFire from Serbia. preview with calendar: 640x480, 800x480, 800x600, 1024x768, 1024x1024, 1152x864, 1280x720, 1280x800, 1280x960, 1280x1024, 1400x1050, 1440x900, 1600x1200, 1680x1050, 1680x1200, 1920x1080, 1920x1200, 1920x1440, 2560x1440 without calendar: 640x480, 800x480, 800x600, 1024x768, 1024x1024, 1152x864, 1280x720, 1280x800, 1280x960, 1280x1024, 1400x1050, 1440x900, 1600x1200, 1680x1050, 1680x1200, 1920x1080, 1920x1200, 1920x1440, 2560x1440 Mochi Designed by Ricardo Gimenes from Spain. preview with calendar: 640x480, 800x480, 800x600, 1024x768, 1024x1024, 1152x864, 1280x720, 1280x800, 1280x960, 1280x1024, 1366x768, 1400x1050, 1440x900, 1600x1200, 1680x1050, 1680x1200, 1920x1080, 1920x1200, 1920x1440, 2560x1440, 3840x2160 without calendar: 640x480, 800x480, 800x600, 1024x768, 1024x1024, 1152x864, 1280x720, 1280x800, 1280x960, 1280x1024, 1366x768, 1400x1050, 1440x900, 1600x1200, 1680x1050, 1680x1200, 1920x1080, 1920x1200, 1920x1440, 2560x1440, 3840x2160 Cyber Voodoo Designed by Ricardo Gimenes from Spain. preview with calendar: 640x480, 800x480, 800x600, 1024x768, 1024x1024, 1152x864, 1280x720, 1280x800, 1280x960, 1280x1024, 1366x768, 1400x1050, 1440x900, 1600x1200, 1680x1050, 1680x1200, 1920x1080, 1920x1200, 1920x1440, 2560x1440, 3840x2160 without calendar: 640x480, 800x480, 800x600, 1024x768, 1024x1024, 1152x864, 1280x720, 1280x800, 1280x960, 1280x1024, 1366x768, 1400x1050, 1440x900, 1600x1200, 1680x1050, 1680x1200, 1920x1080, 1920x1200, 1920x1440, 2560x1440, 3840x2160 Pop Into Fun “Blow the biggest bubbles, chew on the sweetest memories, and let your inner kid shine! Celebrate Bubble Gum Day with us and share the joy of every POP!” — Designed by PopArt Studio from Serbia. preview with calendar: 320x480, 640x480, 800x480, 800x600, 1024x768, 1024x1024, 1152x864, 1280x720, 1280x800, 1280x960, 1280x1024, 1400x1050, 1440x900, 1600x1200, 1680x1050, 1680x1200, 1920x1080, 1920x1200, 1920x1440, 2560x1440 without calendar: 320x480, 640x480, 800x480, 800x600, 1024x768, 1024x1024, 1152x864, 1280x720, 1280x800, 1280x960, 1280x1024, 1400x1050, 1440x900, 1600x1200, 1680x1050, 1680x1200, 1920x1080, 1920x1200, 1920x1440, 2560x1440 Believe “‘Believe’ reminds us to trust ourselves and our potential. It fuels faith, even in challenges, and drives us to pursue our dreams. Belief unlocks strength to overcome obstacles and creates possibilities. It’s the foundation of success, starting with the courage to believe.” — Designed by Hitesh Puri from Delhi, India. preview with calendar: 1280x800, 1280x960, 1280x1024, 1366x768, 1400x1050, 1440x900, 1600x1200, 1680x1050, 1680x1200, 1920x1080, 1920x1200, 1920x1440, 2560x1440 without calendar: 1280x800, 1280x960, 1280x1024, 1366x768, 1400x1050, 1440x900, 1600x1200, 1680x1050, 1680x1200, 1920x1080, 1920x1200, 1920x1440, 2560x1440 Plants “I wanted to draw some very cozy place, both realistic and cartoonish, filled with little details. A space with a slightly unreal atmosphere that some great shops or cafes have. A mix of plants, books, bottles, and shelves seemed like a perfect fit. I must admit, it took longer to draw than most of my other pictures! But it was totally worth it. Watch the making-of.” — Designed by Vlad Gerasimov from Georgia. preview without calendar: 800x480, 800x600, 1024x600, 1024x768, 1152x864, 1280x720, 1280x800, 1280x960, 1280x1024, 1366x768, 1400x1050, 1440x900, 1440x960, 1600x900, 1600x1200, 1680x1050, 1680x1200, 1920x1080, 1920x1200, 1920x1440, 2560x1440, 2560x1600, 2880x1800, 3072x1920, 3840x2160, 5120x2880 Love Is In The Play “Forget Lady and the Tramp and their spaghetti kiss, ’cause Snowflake and Cloudy are enjoying their bliss. The cold and chilly February weather made our kitties knit themselves a sweater. Knitting and playing, the kitties tangled in the yarn and fell in love in your neighbor’s barn.” — Designed by PopArt Studio from Serbia. preview without calendar: 320x480, 640x480, 800x480, 800x600, 1024x768, 1024x1024, 1152x864, 1280x720, 1280x800, 1280x960, 1280x1024, 1366x768, 1400x1050, 1440x900, 1600x1200, 1680x1050, 1680x1200, 1920x1080, 1920x1200, 1920x1440, 2560x1440 Farewell, Winter “Although I love winter (mostly because of the fun winter sports), there are other great activities ahead. Thanks, winter, and see you next year!” — Designed by Igor Izhik from Canada. preview without calendar: 1024x768, 1024x1024, 1152x864, 1280x720, 1280x800, 1280x960, 1280x1024, 1400x1050, 1440x900, 1600x1200, 1680x1050, 1680x1200, 1920x1080, 1920x1200, 1920x1440, 2560x1440, 2560x1600 True Love Designed by Ricardo Gimenes from Spain. preview without calendar: 640x480, 800x480, 800x600, 1024x768, 1024x1024, 1152x864, 1280x720, 1280x800, 1280x960, 1280x1024, 1366x768, 1400x1050, 1440x900, 1600x1200, 1680x1050, 1680x1200, 1920x1080, 1920x1200, 1920x1440, 2560x1440, 3840x2160 Balloons Designed by Xenia Latii from Germany. preview without calendar: 320x480, 640x480, 800x480, 800x600, 1024x768, 1152x864, 1280x720, 1280x800, 1280x960, 1280x1024, 1366x768, 1400x1050, 1440x900, 1600x1200, 1680x1050, 1680x1200, 1920x1080, 1920x1200, 1920x1440, 2560x1440 Magic Of Music Designed by Vlad Gerasimov from Georgia. preview without calendar: 800x480, 800x600, 1024x600, 1024x768, 1152x864, 1280x720, 1280x800, 1280x960, 1280x1024, 1366x768, 1400x1050, 1440x900, 1440x960, 1600x900, 1600x1200, 1680x1050, 1680x1200, 1920x1080, 1920x1200, 1920x1440, 2560x1440, 2560x1600, 2880x1800, 3072x1920, 3840x2160, 5120x2880 Febpurrary “I was doodling pictures of my cat one day and decided I could turn it into a fun wallpaper — because a cold, winter night in February is the perfect time for staying in and cuddling with your cat, your significant other, or both!” — Designed by Angelia DiAntonio from Ohio, USA. preview without calendar: 320x480, 800x480, 1024x768, 1024x1024, 1152x864, 1280x720, 1280x1024, 1366x768, 1400x1050, 1440x900, 1600x1200, 1680x1200, 1920x1080, 1920x1200, 1920x1440, 2560x1440 Dog Year Ahead Designed by PopArt Studio from Serbia. preview without calendar: 320x480, 640x480, 800x480, 800x600, 1024x768, 1024x1024, 1152x864, 1280x720, 1280x800, 1280x960, 1280x1024, 1366x768, 1400x1050, 1440x900, 1600x1200, 1680x1050, 1680x1200, 1920x1080, 1920x1200, 1920x1440, 2560x1440 Good Times Ahead Designed by Ricardo Gimenes from Spain. preview without calendar: 640x480, 800x480, 800x600, 1024x768, 1024x1024, 1152x864, 1280x720, 1280x800, 1280x960, 1280x1024, 1366x768, 1400x1050, 1440x900, 1600x1200, 1680x1050, 1680x1200, 1920x1080, 1920x1200, 1920x1440, 2560x1440, 3840x2160 Romance Beneath The Waves “The 14th of February is just around the corner. And love is in the air, water, and everywhere!” — Designed by Teodora Vasileva from Bulgaria. preview without calendar: 640x480, 800x480, 800x600, 1024x768, 1280x720, 1280x960, 1280x1024, 1400x1050, 1680x1050, 1680x1200, 1920x1080, 1920x1200, 1920x1440, 2560x1440 February Ferns Designed by Nathalie Ouederni from France. preview without calendar: 320x480, 1024x768, 1280x1024, 1440x900, 1680x1200, 1920x1200, 2560x1440 The Great Beyond Designed by Lars Pauwels from Belgium. preview without calendar: 800x600, 1024x768, 1024x1024, 1152x864, 1280x720, 1280x800, 1280x960, 1280x1024, 1366x768, 1400x1050, 1440x900, 1600x1200, 1680x1050, 1680x1200, 1920x1080, 1920x1200, 1920x1440, 2560x1440 It’s A Cupcake Kind Of Day “Sprinkles are fun, festive, and filled with love… especially when topped on a cupcake! Everyone is creative in their own unique way, so why not try baking some cupcakes and decorating them for your sweetie this month? Something homemade, like a cupcake or DIY craft, is always a sweet gesture.” — Designed by Artsy Cupcake from the United States. preview without calendar: 320x480, 640x480, 800x600, 1024x768, 1152x864, 1280x800, 1280x1024, 1366x768, 1440x900, 1600x1200, 1680x1200, 1920x1200, 1920x1440, 2560x1440 Snow Designed by Elise Vanoorbeek from Belgium. preview without calendar: <a href="https://smashingmagazine.com/files/wallpapers/feb-15/snow/nocal/feb-15-snow-nocal-1024x768.jpg title="Snow - 1024x768">1024x768, <a href="https://smashingmagazine.com/files/wallpapers/feb-15/snow/nocal/feb-15-snow-nocal-1152x864.jpg title="Snow - 1152x864">1152x864, <a href="https://smashingmagazine.com/files/wallpapers/feb-15/snow/nocal/feb-15-snow-nocal-1280x720.jpg title="Snow - 1280x720">1280x720, <a href="https://smashingmagazine.com/files/wallpapers/feb-15/snow/nocal/feb-15-snow-nocal-1280x800.jpg title="Snow - 1280x800">1280x800, <a href="https://smashingmagazine.com/files/wallpapers/feb-15/snow/nocal/feb-15-snow-nocal-1280x960.jpg title="Snow - 1280x960">1280x960, <a href="https://smashingmagazine.com/files/wallpapers/feb-15/snow/nocal/feb-15-snow-nocal-1440x900.jpg title="Snow - 1440x900">1440x900, <a href="https://smashingmagazine.com/files/wallpapers/feb-15/snow/nocal/feb-15-snow-nocal-1600x1200.jpg title="Snow - 1600x1200">1600x1200, <a href="https://smashingmagazine.com/files/wallpapers/feb-15/snow/nocal/feb-15-snow-nocal-1680x1050.jpg title="Snow - 1680x1050">1680x1050, <a href="https://smashingmagazine.com/files/wallpapers/feb-15/snow/nocal/feb-15-snow-nocal-1920x1080.jpg title="Snow - 1920x1080">1920x1080, <a href="https://smashingmagazine.com/files/wallpapers/feb-15/snow/nocal/feb-15-snow-nocal-1920x1200.jpg title="Snow - 1920x1200">1920x1200, <a href="https://smashingmagazine.com/files/wallpapers/feb-15/snow/nocal/feb-15-snow-nocal-1920x1440.jpg title="Snow - 1920x1440">1920x1440, <a href="https://smashingmagazine.com/files/wallpapers/feb-15/snow/nocal/feb-15-snow-nocal-2560x1440.jpg title="Snow - 2560x1440">2560x1440, <a href="https://smashingmagazine.com/files/wallpapers/feb-15/snow/nocal/feb-15-snow-nocal-1366x768.jpg title="Snow - 1366x768">1366x768, <a href="https://smashingmagazine.com/files/wallpapers/feb-15/snow/nocal/feb-15-snow-nocal-2880x1800.jpg title="Snow - 2880x1800">2880x1800 Share The Same Orbit! “I prepared a simple and chill layout design for February called ‘Share The Same Orbit!’ which suggests to share the love orbit.” — Designed by Valentin Keleti from Romania. preview without calendar: 320x480, 640x480, 800x480, 800x600, 1024x768, 1024x1024, 1152x864, 1280x720, 1280x800, 1280x960, 1280x1024, 1366x768, 1400x1050, 1440x900, 1600x1200, 1680x1050, 1680x1200, 1920x1080, 1920x1200, 1920x1440, 2560x1440 Dark Temptation “A dark romantic feel, walking through the city on a dark and rainy night.” — Designed by Matthew Talebi from the United States. preview without calendar: 1400x1050, 1440x900, 1600x1200, 1680x1050, 1680x1200, 1920x1080, 1920x1200, 1920x1440, 2560x1440 Ice Cream Love “My inspiration for this wallpaper is the biggest love someone can have in life: the love for ice cream!” — Designed by Zlatina Petrova from Bulgaria. preview without calendar: 320x480, 640x480, 800x480, 800x600, 1024x768, 1024x1024, 1152x864, 1280x720, 1280x800, 1280x960, 1280x1024, 1400x1050, 1440x900, 1600x1200, 1680x1050, 1680x1200, 1920x1080, 1920x1200, 1920x1440, 2560x1440 Lovely Day Designed by Ricardo Gimenes from Spain. preview without calendar: 320x480, 640x480, 800x480, 800x600, 1024x768, 1024x1024, 1152x864, 1280x720, 1280x800, 1280x960, 1280x1024, 1366x768, 1400x1050, 1440x900, 1600x1200, 1680x1050, 1680x1200, 1920x1080, 1920x1200, 1920x1440, 2560x1440 Time Thief “Who has stolen our time? Maybe the time thief, so be sure to enjoy the other 28 days of February.” — Designed by Colorsfera from Spain. preview without calendar: 320x480, 640x480, 800x480, 800x600, 1024x768, 1024x1024, 1152x864, 1260x1440, 1280x720, 1280x800, 1280x960, 1280x1024, 1400x1050, 1440x900, 1600x1200, 1680x1050, 1680x1200, 1920x1080, 1920x1200, 1920x1440, 2560x1440 In Another Place At The Same Time “February is the month of love par excellence, but also a different month. Perhaps because it is shorter than the rest or because it is the one that makes way for spring, but we consider it a special month. It is a perfect month to make plans because we have already finished the post-Christmas crunch and we notice that spring and summer are coming closer. That is why I like to imagine that maybe in another place someone is also making plans to travel to unknown lands.” — Designed by Verónica Valenzuela from Spain. preview without calendar: 800x480, 1024x768, 1152x864, 1280x800, 1280x960, 1440x900, 1680x1200, 1920x1080, 2560x1440 French Fries Designed by Doreen Bethge from Germany. preview without calendar: 320x480, 640x480, 800x480, 800x600, 1024x768, 1024x1024, 1152x864, 1280x720, 1280x800, 1280x960, 1280x1024, 1366x768, 1400x1050, 1440x900, 1600x1200, 1680x1050, 1680x1200, 1920x1080, 1920x1200, 1920x1440, 2560x1440 Frozen Worlds “A view of two frozen planets, lots of blue tints.” — Designed by Rutger Berghmans from Belgium. preview without calendar: 1280x800, 1366x768, 1440x900, 1680x1050, 1920x1080, 1920x1200, 2560x1440 Out There, There’s Someone Like You “I am a true believer that out there in this world there is another person who is just like us, the problem is to find her/him.” — Designed by Maria Keller from Mexico. preview without calendar: 320x480, 640x480, 640x1136, 750x1334, 800x480, 800x600, 1024x768, 1024x1024, 1152x864, 1242x2208, 1280x720, 1280x800, 1280x960, 1280x1024, 1366x768, 1400x1050, 1440x900, 1600x1200, 1680x1050, 1680x1200, 1920x1080, 1920x1200, 1920x1440, 2560x1440, 2880x1800 “Greben” Icebreaker “Danube is Europe’s second largest river, connecting ten different countries. In these cold days, when ice paralyzes rivers and closes waterways, a small but brave icebreaker called Greben (Serbian word for ‘reef’) seems stronger than winter. It cuts through the ice on Đerdap gorge (Iron Gate) — the longest and biggest gorge in Europe — thus helping the production of electricity in the power plant. This is our way to give thanks to Greben!” — Designed by PopArt Studio from Serbia. preview without calendar: 320x480, 640x480, 800x480, 800x600, 1024x768, 1024x1024, 1152x864, 1280x720, 1280x800, 1280x960, 1280x1024, 1366x768, 1400x1050, 1440x900, 1600x1200, 1680x1050, 1680x1200, 1920x1080, 1920x1200, 1920x1440, 2560x1440 Sharp “I was sick recently and squinting through my blinds made a neat effect with shapes and colors.” — Designed by Dylan Baumann from Omaha, NE. preview without calendar: 320x480, 640x480, 800x600, 1024x1024, 1280x1024, 1600x1200, 1680x1200, 1920x1080, 1920x1440, 2560x1440 On The Light Side Designed by Ricardo Gimenes from Spain. preview without calendar: 640x480, 800x480, 800x600, 1024x768, 1024x1024, 1152x864, 1280x720, 1280x800, 1280x960, 1280x1024, 1366x768, 1400x1050, 1440x900, 1600x1200, 1680x1050, 1680x1200, 1920x1080, 1920x1200, 1920x1440, 2560x1440, 3840x2160, printable PDF Febrewery “I live in Madison, WI, which is famous for its breweries. Wisconsin even named their baseball team “The Brewers.” If you like beer, brats, and lots of cheese, it’s the place for you!” — Designed by Danny Gugger from the United States. preview without calendar: 320x480, 1020x768, 1280x800, 1280x1024, 1136x640, 2560x1440 Love Angel Vader “Valentine’s Day is coming? Noooooooooooo!” — Designed by Ricardo Gimenes from Spain. preview without calendar: 320x480, 640x960, 1024x768, 1024x1024, 1280x800, 1280x960, 1280x1024, 1366x768, 1400x1050, 1440x900, 1600x1050, 1600x1200, 1680x1050, 1680x1200, 1920x1080, 1920x1200, 1920x1440, 2560x1440, 2880x1800 Made In Japan “See the beautiful colors, precision, and the nature of Japan in one picture.” — Designed by Fatih Yilmaz from the Netherlands. preview without calendar: 1280x720, 1280x960, 1400x1050, 1440x900, 1600x1200, 1680x1200, 1920x1080, 1920x1440, 2560x1440, 3840x2160 Groundhog “The Groundhog emerged from its burrow on February 2. If it is cloudy, then spring will come early, but if it is sunny, the groundhog will see its shadow, will retreat back into its burrow, and the winter weather will continue for six more weeks.” — Designed by Oscar Marcelo from Portugal. preview without calendar: 1280x720, 1280x800, 1280x960, 1280x1024, 1440x900, 1680x1050, 1920x1080, 1920x1200, 2560x1440

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      The Digital Playbook: A Crucial Counterpart To Your Design System

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        Design systems play a crucial role in today’s digital landscape, providing a blueprint for consistent and user-friendly interfaces. But there’s another tool that deserves equal attention: the digital playbook.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        I recently wrote for Smashing Magazine about how UX leaders face increasing pressure to deliver more with limited resources. Let me show you how a digital playbook can help meet this challenge by enhancing our work’s visibility while boosting efficiency. While a design system ensures visual coherence, a digital playbook lays out the strategic and operational framework for how digital projects should be executed and managed. Here’s why a digital playbook deserves a place in your organization’s toolbox and what it should include to drive meaningful impact. What Is A Digital Playbook? A digital playbook is essentially your organization’s handbook for navigating the complexities of digital work. As a user experience consultant, I often help organizations create tools like this to streamline their processes and improve outcomes. It’s a collection of strategies, principles, and processes that provide clarity on how to handle everything from website creation to content management and beyond. Think of it as a how-to guide for all things digital. Unlike rigid rulebooks that feel constraining, you’ll find that a playbook evolves with your organization’s unique culture and challenges. You can use it to help stakeholders learn, standardize your work, and help everybody be more effective. Let me show you how a playbook can transform the way your team works. Why You Need A Digital Playbook Have you ever faced challenges like these? Stakeholders with conflicting expectations of what the digital team should deliver. Endless debates over project priorities and workflows that stall progress. A patchwork of tools and inconsistent policies that create confusion. Uncertainty about best practices, leading to inefficiencies and missed opportunities. Let me show you how a playbook can help you and your team in four key ways: It helps you educate your stakeholders by making digital processes transparent and building trust. I’ve found that when you explain best practices clearly, everyone gets on the same page quickly. You’ll streamline your processes with clear, standardized workflows. This means less confusion and faster progress on your projects. Your digital team gains more credibility as you step into a leadership role. You’ll be able to show your real value to the organization. Best of all, you’ll reduce friction in your daily work. When everyone understands the policies, you’ll face fewer misunderstandings and conflicts. A digital playbook isn’t just a tool; it’s a way to transform challenges into opportunities for greater impact. But, no doubt you are wondering, what exactly goes into a digital playbook? Key Components Of A Digital Playbook Every digital playbook is unique, but if you’ve ever wondered where to start, here are some key areas to consider. Let’s walk through them together. Engaging With The Digital Team Have you ever had people come to you too late in the process or approach you with solutions rather than explaining the underlying problems? A playbook can help mitigate these issues by providing clear guidance on: How to request a new website or content update at the right time; What information you require to do your job; What stakeholders need to consider before requesting your help. By addressing these common challenges, you’re not just reducing your frustrations — you’re educating stakeholders and encouraging better collaboration. Digital Project Lifecycle Most digital projects can feel overwhelming without a clear structure, especially for stakeholders who may not understand the intricacies of the process. That’s why it’s essential to communicate the key phases clearly to those requesting your team’s help. For example: Discovery: Explain how your team will research goals, user needs, and requirements to ensure the project starts on solid ground. Prototyping: Highlight the importance of testing initial concepts to validate ideas before full development. Build: Detail the process of developing the final product and incorporating feedback. Launch: Set clear expectations for rolling out the project with a structured plan. Management: Clarify how the team will optimize and maintain the product over time. Retirement: Help stakeholders understand when and how to phase out outdated tools or content effectively. I’ve structured the lifecycle this way to help stakeholders understand what to expect. When they know what’s happening at each stage, it builds trust and helps the working relationship. Stakeholders will see exactly what role you play and how your team adds value throughout the process. Publishing Best Practices Writing for the web isn’t the same as traditional writing, and it’s critical for your team to help stakeholders understand the differences. Your playbook can include practical advice to guide them, such as: Planning and organizing content to align with user needs and business goals. Crafting content that’s user-friendly, SEO-optimized, and designed for clarity. Maintaining accessible and high-quality standards to ensure inclusivity. By providing this guidance, you empower stakeholders to create content that’s not only effective but also reflects your team’s standards. Understanding Your Users Helping stakeholders understand your audience is essential for creating user-centered experiences. Your digital playbook can support this by including: Detailed user personas that highlight specific needs and behaviors. Recommendations for tools and methods to gather and analyze user data. Practical tips for ensuring digital experiences are inclusive and accessible to all. By sharing this knowledge, your team helps stakeholders make decisions that prioritize users, ultimately leading to more successful outcomes. Recommended Resources Stakeholders often are unaware of the wealth of resources that can help them improve their digital deliverables. Your playbook can help by recommending trusted solutions, such as: Tools that enable stakeholders to carry out their own user research and testing. Analytics tools that allow stakeholders to track the performance of their websites. A list of preferred suppliers in case stakeholders need to bring in external experts. These recommendations ensure stakeholders are equipped with reliable resources that align with your team’s processes. Policies And Governance Uncertainty about organizational policies can lead to confusion and missteps. Your playbook should provide clarity by outlining: Accessibility and inclusivity standards to ensure compliance and user satisfaction. Data privacy and security protocols to safeguard user information. Clear processes for prioritizing and governing projects to maintain focus and consistency. By setting these expectations, your team establishes a foundation of trust and accountability that stakeholders can rely on. Of course, you can have the best digital playbook in the world, but if people don’t reference it, then it is a wasted opportunity. Making Your Digital Playbook Stick It falls to you and your team to ensure as many stakeholders as possible engage with your playbook. Try the following: Make It Easy to Find How often do stakeholders struggle to find important resources? Avoid hosting the playbook in a forgotten corner of your intranet. Instead, place it front and center on a well-maintained, user-friendly site that’s accessible to everyone. Keep It Engaging Let’s face it — nobody wants to sift through walls of text. Use visuals like infographics, short explainer videos, and clear headings to make your playbook not only digestible but also enjoyable to use. Think of it as creating a resource your stakeholders will actually want to refer back to. Frame It as a Resource A common pitfall is presenting the playbook as a rigid set of rules. Instead, position it as a helpful guide designed to make everyone’s work easier. Highlight how it can simplify workflows, improve outcomes, and solve real-world problems your stakeholders face daily. Share at Relevant Moments Don’t wait for stakeholders to find the playbook themselves. Instead, proactively share relevant sections when they’re most needed. For example, send the discovery phase documentation when starting a new project or share content guidelines when someone is preparing to write for the website. This just-in-time approach ensures the playbook’s guidance is applied when it matters most. Start Small, Then Scale Creating a digital playbook might sound like a daunting task, but it doesn’t have to be. Begin with a few core sections and expand over time. Assign ownership to a specific team or individual to ensure it remains updated and relevant. In the end, a digital playbook is an investment. It saves time, reduces conflicts, and elevates your organization’s digital maturity. Just as a design system is critical for visual harmony, a digital playbook is essential for operational excellence. Further Reading On SmashingMag “Design Patterns Are A Better Way To Collaborate On Your Design System,” Ben Clemens “Design Systems: Useful Examples and Resources,” Cosima Mielke “Building Components For Consumption, Not Complexity (Part 1),” Luis Ouriach “Taking The Stress Out Of Design System Management,” Masha Shaposhnikova

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        Transitioning Top-Layer Entries And The Display Property In CSS

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          It’s not always the big features that make our everyday lives easier; sometimes, it’s those ease-of-life features that truly enhance our projects. In this article, Brecht De Ruyte highlights two such features: `@starting-style` and `transition-behavior` — two properties that are absolutely welcome additions to your everyday work with CSS animations.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          Animating from and to display: none; was something we could only achieve with JavaScript to change classes or create other hacks. The reason why we couldn’t do this in CSS is explained in the new CSS Transitions Level 2 specification: “In Level 1 of this specification, transitions can only start during a style change event for elements that have a defined before-change style established by the previous style change event. That means a transition could not be started on an element that was not being rendered for the previous style change event.” In simple terms, this means that we couldn’t start a transition on an element that is hidden or that has just been created. What Does transition-behavior: allow-discrete Do? allow-discrete is a bit of a strange name for a CSS property value, right? We are going on about transitioning display: none, so why isn’t this named transition-behavior: allow-display instead? The reason is that this does a bit more than handling the CSS display property, as there are other “discrete” properties in CSS. A simple rule of thumb is that discrete properties do not transition but usually flip right away between two states. Other examples of discrete properties are visibility and mix-blend-mode. I’ll include an example of these at the end of this article. To summarise, setting the transition-behavior property to allow-discrete allows us to tell the browser it can swap the values of a discrete property (e.g., display, visibility, and mix-blend-mode) at the 50% mark instead of the 0% mark of a transition. What Does @starting-style Do? The @starting-style rule defines the styles of an element right before it is rendered to the page. This is highly needed in combination with transition-behavior and this is why: When an item is added to the DOM or is initially set to display: none, it needs some sort of “starting style” from which it needs to transition. To take the example further, popovers and dialog elements are added to a top layer which is a layer that is outside of your document flow, you can kind of look at it as a sibling of the <html> element in your page’s structure. Now, when opening this dialog or popover, they get created inside that top layer, so they don’t have any styles to start transitioning from, which is why we set @starting-style. Don’t worry if all of this sounds a bit confusing. The demos might make it more clearly. The important thing to know is that we can give the browser something to start the animation with since it otherwise has nothing to animate from. A Note On Browser Support At the moment of writing, the transition-behavior is available in Chrome, Edge, Safari, and Firefox. It’s the same for @starting-style, but Firefox currently does not support animating from display: none. But remember that everything in this article can be perfectly used as a progressive enhancement. Now that we have the theory of all this behind us, let’s get practical. I’ll be covering three use cases in this article: Animating from and to display: none in the DOM. Animating dialogs and popovers entering and exiting the top layer. More “discrete properties” we can handle. Animating From And To display: none In The DOM For the first example, let’s take a look at @starting-style alone. I created this demo purely to explain the magic. Imagine you want two buttons on a page to add or remove list items inside of an unordered list. This could be your starting HTML: <button type="button" class="btn-add"> Add item </button> <button type="button" class="btn-remove"> Remove item </button> <ul role="list"></ul> Next, we add actions that add or remove those list items. This can be any method of your choosing, but for demo purposes, I quickly wrote a bit of JavaScript for it: document.addEventListener("DOMContentLoaded", () => { const addButton = document.querySelector(".btn-add"); const removeButton = document.querySelector(".btn-remove"); const list = document.querySelector('ul[role="list"]'); addButton.addEventListener("click", () => { const newItem = document.createElement("li"); list.appendChild(newItem); }); removeButton.addEventListener("click", () => { if (list.lastElementChild) { list.lastElementChild.classList.add("removing"); setTimeout(() => { list.removeChild(list.lastElementChild); }, 200); } }); }); When clicking the addButton, an empty list item gets created inside of the unordered list. When clicking the removeButton, the last item gets a new .removing class and finally gets taken out of the DOM after 200ms. With this in place, we can write some CSS for our items to animate the removing part: ul { li { transition: opacity 0.2s, transform 0.2s; &.removing { opacity: 0; transform: translate(0, 50%); } } } This is great! Our .removing animation is already looking perfect, but what we were looking for here was a way to animate the entry of items coming inside of our DOM. For this, we will need to define those starting styles, as well as the final state of our list items. First, let’s update the CSS to have the final state inside of that list item: ul { li { opacity: 1; transform: translate(0, 0); transition: opacity 0.2s, transform 0.2s; &.removing { opacity: 0; transform: translate(0, 50%); } } } Not much has changed, but now it’s up to us to let the browser know what the starting styles should be. We could set this the same way we did the .removing styles like so: ul { li { opacity: 1; transform: translate(0, 0); transition: opacity 0.2s, transform 0.2s; @starting-style { opacity: 0; transform: translate(0, 50%); } &.removing { opacity: 0; transform: translate(0, 50%); } } } Now we’ve let the browser know that the @starting-style should include zero opacity and be slightly nudged to the bottom using a transform. The final result is something like this: But we don’t need to stop there! We could use different animations for entering and exiting. We could, for example, update our starting style to the following: @starting-style { opacity: 0; transform: translate(0, -50%); } Doing this, the items will enter from the top and exit to the bottom. See the full example in this CodePen: See the Pen @starting-style demo - up-in, down-out [forked] by utilitybend. When To Use transition-behavior: allow-discrete In the previous example, we added and removed items from our DOM. In the next demo, we will show and hide items using the CSS display property. The basic setup is pretty much the same, except we will add eight list items to our DOM with the .hidden class attached to it: <button type="button" class="btn-add"> Show item </button> <button type="button" class="btn-remove"> Hide item </button> <ul role="list"> <li class="hidden"></li> <li class="hidden"></li> <li class="hidden"></li> <li class="hidden"></li> <li class="hidden"></li> <li class="hidden"></li> <li class="hidden"></li> <li class="hidden"></li> </ul> Once again, for demo purposes, I added a bit of JavaScript that, this time, removes the .hidden class of the next item when clicking the addButton and adds the hidden class back when clicking the removeButton: document.addEventListener("DOMContentLoaded", () => { const addButton = document.querySelector(".btn-add"); const removeButton = document.querySelector(".btn-remove"); const listItems = document.querySelectorAll('ul[role="list"] li'); let activeCount = 0; addButton.addEventListener("click", () => { if (activeCount < listItems.length) { listItems[activeCount].classList.remove("hidden"); activeCount++; } }); removeButton.addEventListener("click", () => { if (activeCount > 0) { activeCount--; listItems[activeCount].classList.add("hidden"); } }); }); Let’s put together everything we learned so far, add a @starting-style to our items, and do the basic setup in CSS: ul { li { display: block; opacity: 1; transform: translate(0, 0); transition: opacity 0.2s, transform 0.2s; @starting-style { opacity: 0; transform: translate(0, -50%); } &.hidden { display: none; opacity: 0; transform: translate(0, 50%); } } } This time, we have added the .hidden class, set it to display: none, and added the same opacity and transform declarations as we previously did with the .removing class in the last example. As you might expect, we get a nice fade-in for our items, but removing them is still very abrupt as we set our items directly to display: none. This is where the transition-behavior property comes into play. To break it down a bit more, let’s remove the transition property shorthand of our previous CSS and open it up a bit: ul { li { display: block; opacity: 1; transform: translate(0, 0); transition-property: opacity, transform; transition-duration: 0.2s; } } All that is left to do is transition the display property and set the transition-behavior property to allow-discrete: ul { li { display: block; opacity: 1; transform: translate(0, 0); transition-property: opacity, transform, display; transition-duration: 0.2s; transition-behavior: allow-discrete; /* etc. */ } } We are now animating the element from display: none, and the result is exactly as we wanted it: We can use the transition shorthand property to make our code a little less verbose: transition: opacity 0.2s, transform 0.2s, display 0.2s allow-discrete; You can add allow-discrete in there. But if you do, take note that if you declare a shorthand transition after transition-behavior, it will be overruled. So, instead of this: transition-behavior: allow-discrete; transition: opacity 0.2s, transform 0.2s, display 0.2s; …we want to declare transition-behavior after the transition shorthand: transition: opacity 0.2s, transform 0.2s, display 0.2s; transition-behavior: allow-discrete; Otherwise, the transition shorthand property overrides transition-behavior. See the Pen @starting-style and transition-behavior: allow-discrete [forked] by utilitybend. Animating Dialogs And Popovers Entering And Exiting The Top Layer Let’s add a few use cases with dialogs and popovers. Dialogs and popovers are good examples because they get added to the top layer when opening them. What Is That Top Layer? We’ve already likened the “top layer” to a sibling of the <html> element, but you might also think of it as a special layer that sits above everything else on a web page. It's like a transparent sheet that you can place over a drawing. Anything you draw on that sheet will be visible on top of the original drawing. The original drawing, in this example, is the DOM. This means that the top layer is out of the document flow, which provides us with a few benefits. For example, as I stated before, dialogs and popovers are added to this top layer, and that makes perfect sense because they should always be on top of everything else. No more z-index: 9999! But it’s more than that: z-index is irrelevant: Elements on the top layer are always on top, regardless of their z-index value. DOM hierarchy doesn’t matter: An element’s position in the DOM doesn’t affect its stacking order on the top layer. Backdrops: We get access to a new ::backdrop pseudo-element that lets us style the area between the top layer and the DOM beneath it. Hopefully, you are starting to understand the importance of the top layer and how we can transition elements in and out of it as we would with popovers and dialogues. Transitioning The Dialog Element In The Top Layer The following HTML contains a button that opens a <dialog> element, and that <dialog> element contains another button that closes the <dialog>. So, we have one button that opens the <dialog> and one that closes it. <button class="open-dialog" data-target="my-modal">Show dialog</button> <dialog id="my-modal"> <p>Hi, there!</p> <button class="outline close-dialog" data-target="my-modal"> close </button> </dialog> A lot is happening in HTML with invoker commands that will make the following step a bit easier, but for now, let’s add a bit of JavaScript to make this modal actually work: // Get all open dialog buttons. const openButtons = document.querySelectorAll(".open-dialog"); // Get all close dialog buttons. const closeButtons = document.querySelectorAll(".close-dialog"); // Add click event listeners to open buttons. openButtons.forEach((button) =< { button.addEventListener("click", () =< { const targetId = button.getAttribute("data-target"); const dialog = document.getElementById(targetId); if (dialog) { dialog.showModal(); } }); }); // Add click event listeners to close buttons. closeButtons.forEach((button) =< { button.addEventListener("click", () =< { const targetId = button.getAttribute("data-target"); const dialog = document.getElementById(targetId); if (dialog) { dialog.close(); } }); }); I’m using the following styles as a starting point. Notice how I’m styling the ::backdrop as an added bonus! dialog { padding: 30px; width: 100%; max-width: 600px; background: #fff; border-radius: 8px; border: 0; box-shadow: rgba(0, 0, 0, 0.3) 0px 19px 38px, rgba(0, 0, 0, 0.22) 0px 15px 12px; &::backdrop { background-image: linear-gradient( 45deg in oklab, oklch(80% 0.4 222) 0%, oklch(35% 0.5 313) 100% ); } } This results in a pretty hard transition for the entry, meaning it’s not very smooth: Let’s add transitions to this dialog element and the backdrop. I’m going a bit faster this time because by now, you likely see the pattern and know what’s happening: dialog { opacity: 0; translate: 0 30%; transition-property: opacity, translate, display; transition-duration: 0.8s; transition-behavior: allow-discrete; &[open] { opacity: 1; translate: 0 0; @starting-style { opacity: 0; translate: 0 -30%; } } } When a dialog is open, the browser slaps an open attribute on it: <dialog open> ... </dialog> And that’s something else we can target with CSS, like dialog[open]. So, in this case, we need to set a @starting-style for when the dialog is in an open state. Let’s add a transition for our backdrop while we’re at it: dialog { /* etc. */ &::backdrop { opacity: 0; transition-property: opacity; transition-duration: 1s; } &[open] { /* etc. */ &::backdrop { opacity: 0.8; @starting-style { opacity: 0; } } } } Now you’re probably thinking: A-ha! But you should have added the display property and the transition-behavior: allow-discrete on the backdrop! But no, that is not the case. Even if I would change my backdrop pseudo-element to the following CSS, the result would stay the same: &::backdrop { opacity: 0; transition-property: opacity, display; transition-duration: 1s; transition-behavior: allow-discrete; } It turns out that we are working with a ::backdrop and when working with a ::backdrop, we’re implicitly also working with the CSS overlay property, which specifies whether an element appearing in the top layer is currently rendered in the top layer. And overlay just so happens to be another discrete property that we need to include in the transition-property declaration: dialog { /* etc. */ &::backdrop { transition-property: opacity, display, overlay; /* etc. */ } Unfortunately, this is currently only supported in Chromium browsers, but it can be perfectly used as a progressive enhancement. And, yes, we need to add it to the dialog styles as well: dialog { transition-property: opacity, translate, display, overlay; /* etc. */ &::backdrop { transition-property: opacity, display, overlay; /* etc. */ } See the Pen Dialog: starting-style, transition-behavior, overlay [forked] by utilitybend. It’s pretty much the same thing for a popover instead of a dialog. I’m using the same technique, only working with popovers this time: See the Pen Popover transition with @starting-style [forked] by utilitybend. Other Discrete Properties There are a few other discrete properties besides the ones we covered here. If you remember the second demo, where we transitioned some items from and to display: none, the same can be achieved with the visibility property instead. This can be handy for those cases where you want items to preserve space for the element’s box, even though it is invisible. So, here’s the same example, only using visibility instead of display. See the Pen Transitioning the visibility property [forked] by utilitybend. The CSS mix-blend-mode property is another one that is considered discrete. To be completely honest, I can’t find a good use case for a demo. But I went ahead and created a somewhat trite example where two mix-blend-modes switch right in the middle of the transition instead of right away. See the Pen Transitioning mix-blend-mode [forked] by utilitybend. Wrapping Up That’s an overview of how we can transition elements in and out of the top layer! In an ideal world, we could get away without needing a completely new property like transition-behavior just to transition otherwise “un-transitionable” properties, but here we are, and I’m glad we have it. But we also got to learn about @starting-style and how it provides browsers with a set of styles that we can apply to the start of a transition for an element that’s in the top layer. Otherwise, the element has nothing to transition from at first render, and we’d have no way to transition them smoothly in and out of the top layer.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          Svelte 5 And The Future Of Frameworks: A Chat With Rich Harris

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            After months of anticipation, debate, and even a bit of apprehension, Svelte 5 arrived earlier this year. Frederick O’Brien caught up with its creator, Rich Harris, to talk about the path that brought him and his team here and what lies ahead.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            Svelte occupies a curious space within the web development world. It’s been around in one form or another for eight years now, and despite being used by the likes of Apple, Spotify, IKEA, and the New York Times, it still feels like something of an upstart, maybe even a black sheep. As creator Rich Harris recently put it, “If React is Taylor Swift, we’re more of a Phoebe Bridges. She’s critically acclaimed, and you’ve heard of her, but you probably can’t name that many of her songs.” — Rich Harris This may be why the release of Svelte 5 in October this year felt like such a big deal. It tries to square the circle of convention and innovation. Can it remain one of the best-loved frameworks on the web while shaking off suspicions that it can’t quite rub shoulders with React, Vue, and others when it comes to scalability? Whisper it, but they might just have pulled it off. The post-launch reaction has been largely glowing, with weekly npm downloads doubling compared to six months ago. Still, I’m not in the predictions game. The coming months and years will be the ultimate measure of Svelte 5. And why speculate on the most pressing questions when I can just ask Rich Harris myself? He kindly took some time to chat with me about Svelte and the future of web development. Not Magic, But Magical Svelte 5 is a ground-up rewrite. I don’t want to get into the weeds here — key changes are covered nicely in the migration guide — but suffice it to say the big one where day-to-day users are concerned is runes. At times, magic feeling $ has given way to the more explicit $state, $derived, and $effect. A lot of the talk around Svelte 5 included the sentiment that it marks the ‘maturation’ of the framework. To Harris and the Svelte team, it feels like a culmination, with lessons learned combined with aspirations to form something fresh yet familiar. “This does sort of feel like a new chapter. I’m trying to build something that you don’t feel like you need to get a degree in it before you can be productive in it. And that seems to have been carried through with Svelte 5.” — Rich Harris Although raw usage numbers aren’t everything, seeing the uptick in installations has been a welcome signal for Harris and the Svelte team. “For us, success is definitely not based around adoption, though seeing the number go up and to the right gives us reassurance that we’re doing the right thing and we’re on the right track. Even if it’s not the goal, it is a useful indication. But success is really people building their apps with this framework and building higher quality, more resilient, more accessible apps.” — Rich Harris The tenets of a Svelte philosophy outlined by Harris earlier this year reinforce the point: The web matters. Optimise for vibes. Don’t optimise for adoption. HTML, The Mother Language. Embrace progress. Numbers lie. Magical, not magic. Dream big. No one cares. Design by consensus. Click the link above to hear these expounded upon, but you get the crux. Svelte is very much a qualitative project. Although Svelte performs well in a fair few performance metrics itself, Harris has long been a critic of metrics like Lighthouse being treated as ends in themselves. Fastest doesn’t necessarily mean best. At the end of the day, we are all in the business of making quality websites. Frameworks are a means to that end, and Harris sees plenty of work to be done there. Software Is Broken Every milestone is a cause for celebration. It’s also a natural pause in which to ask, “Now what?” For the Svelte team, the sights seem firmly set on shoring up the quality of the web. “A conclusion that we reached over the course of a recent discussion is that most software in the world is kind of terrible. Things are not good. Half the stuff on my phone just doesn’t work. It fails at basic tasks. And the same is true for a lot of websites. The number of times I’ve had to open DevTools to remove the disabled attribute from a button so that I can submit a form, or been unclear on whether a payment went through or not.” — Rich Harris This certainly meshes with my experience and, doubtless, countless others. Between enshittification, manipulative algorithms, and the seemingly endless influx of AI-generated slop, it’s hard to shake the feeling that the web is becoming increasingly decadent and depraved. “So many pieces of software that we use are just terrible. They’re just bad software. And it’s not because software engineers are idiots. Our main priority as toolmakers should be to enable people to build software that isn’t broken. As a baseline, people should be able to build software that works.” — Rich Harris This sense of responsibility for the creation and maintenance of good software speaks to the Svelte team’s holistic outlook and also looks to influence priorities going forward. Brave New World Part of Svelte 5 feels like a new chapter in the sense of fresh foundations. Anyone who’s worked in software development or web design will tell you how much of a headache ground-up rewrites are. Rebuilding the foundations is something to celebrate when you pull it off, but it also begs the question: What are the foundations for? Harris has his eyes on the wider ecosystem around frameworks. “I don’t think there’s a lot more to do to solve the problem of taking some changing application state and turning it into DOM, but I think there’s a huge amount to be done around the ancillary problems. How do we load the data that we put in those components? Where does that data live? How do we deploy our applications?” — Rich Harris In the short to medium term, this will likely translate into some love for SvelteKit, the web application framework built around Svelte. The framework might start having opinions about authentication and databases, an official component library perhaps, and dev tools in the spirit of the Astro dev toolbar. And all these could be precursors to even bigger explorations. “I want there to be a Rails or a Laravel for JavaScript. In fact, I want there to be multiple such things. And I think that at least part of Svelte’s long-term goal is to be part of that. There are too many things that you need to learn in order to build a full stack application today using JavaScript.” — Rich Harris Why Don’t We Have A Laravel For JavaScript? by Theo Browne “Why We Don’t Have a Laravel For JavaScript... Yet” by Vince Canger Onward Although Svelte has been ticking along happily for years, the release of version 5 has felt like a new lease of life for the ecosystem around it. Every day brings new and exciting projects to the front page of the /r/sveltejs subreddit, while this year’s Advent of Svelte has kept up a sense of momentum following the stable release. Below are just a handful of the Svelte-based projects that have caught my eye: webvm: Virtual Machine for the Web number-flow: An animated number component for React, Vue, and Svelte sveltednd: A lightweight, flexible drag and drop library for Svelte 5 applications Threlte 8 Despite the turbulence and inescapable sense of existential dread surrounding much tech, this feels like an exciting time for web development. The conditions are ripe for lovely new things to emerge. And as for Svelte 5 itself, what does Rich Harris say to those who might be on the fence? “I would say you have nothing to lose but an afternoon if you try it. We have a tutorial that will take you from knowing nothing about Svelte or even existing frameworks. You can go from that to being able to build applications using Svelte in three or four hours. If you just want to learn Svelte basics, then that’s an hour. Try it.” — Rich Harris Further Reading On SmashingMag “How To Build Server-Side Rendered (SSR) Svelte Apps With SvelteKit,” Sriram Thiagarajan “Web Development Is Getting Too Complex, And It May Be Our Fault,” Juan Diego Rodríguez “Vanilla JavaScript, Libraries, And The Quest For Stateful DOM Rendering,” Frederik Dohr “The Hype Around Signals,” Atila Fassina

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            Navigating The Challenges Of Modern Open-Source Authoring: Lessons Learned

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              Alvaro Saburido delves into the current state and challenges of Open-Source authoring, sharing lessons learned from both community- and company-driven initiatives.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              This article is a sponsored by Storyblok Open source is the backbone of modern software development. As someone deeply involved in both community-driven and company-driven open source, I’ve had the privilege of experiencing its diverse approaches firsthand. This article dives into what modern OSS (Open Source) authoring looks like, focusing on front-end JavaScript libraries such as TresJS and tools I’ve contributed to at Storyblok. But let me be clear: There’s no universal playbook for OSS. Every language, framework, and project has its own workflows, rules, and culture — and that’s okay. These variations are what make open source so adaptable and diverse. The Art Of OSS Authoring Authoring an open-source project often begins with scratching your own itch — solving a problem you face as a developer. But as your “experiment” gains traction, the challenge shifts to addressing diverse use cases while maintaining the simplicity and focus of the original idea. Take TresJS as an example. All I wanted was to add 3D to my personal Nuxt portfolio, but at that time, there wasn’t a maintained, feature-rich alternative to React Three Fiber in VueJS. So, I decided to create one. Funny enough, after two years after the library’s launch, my portfolio remains unfinished. Community-driven OSS Authoring: Lessons From TresJS Continuing with TresJS as an example of a community-driven OSS project, the community has been an integral part of its growth, offering ideas, filing issues (around 531 in total), and submitting pull requests (around 936 PRs) of which 90% eventually made it to production. As an author, this is the best thing that can happen — it’s probably one of the biggest reasons I fell in love with open source. The continuous collaboration creates an environment where new ideas can evolve into meaningful contributions. However, it also comes with its own challenges. The more ideas come in, the harder it becomes to maintain the project’s focus on its original purpose. As authors, it’s our responsibility to keep the vision of the library clear — even if that means saying no to great ideas from the community. Over time, some of the most consistent collaborators became part of a core team, helping to share the responsibility of maintaining the library and ensuring it stays aligned with its original goals. Another crucial aspect of scaling a project, especially one like TresJS, which has grown into an ecosystem of packages, is the ability to delegate. The more the project expands, the more essential it becomes to distribute responsibilities among contributors. Delegation helps in reducing the burden of the massive workload and empowers contributors to take ownership of specific areas. As a core author, it’s equally important to provide the necessary tools, CI workflows, and clear conventions to make the process of contributing as simple and efficient as possible. A well-prepared foundation ensures that new and existing collaborators can focus on what truly matters — pushing the project forward. Company-driven OSS Authoring: The Storyblok Perspective Now that we’ve explored the bright spots and challenges of community-driven OSS let’s jump into a different realm: company-driven OSS. I had experience with inner-source and open-source in previous companies, so I already had a grasp of how OSS works in the context of a company environment. However, my most meaningful experience would come later, specifically earlier this year, when I switched my role from DevRel to a full-time Developer Experience Engineer, and I say “full-time” because before taking the role, I was already contributing to Storyblok’s SDK ecosystem. At Storyblok, open source plays a crucial role in how we engage with developers and how they seamlessly use our product with their favorite framework. Our goal is to provide the same developer experience regardless of the flavor, making the experience of using Storyblok as simple, effective, and enjoyable as possible. To achieve this, it’s crucial to balance the needs of the developer community — which often reflect the needs of the clients they work for — with the company’s broader goals. One of the things I find more challenging is managing expectations. For instance, while the community may want feature requests and bug fixes to be implemented quickly, the company’s priorities might dictate focusing on stability, scalability, and often strategic integrations. Clear communication and prioritization are key to maintaining healthy alignment and trust between both sides. One of the unique advantages of company-driven open source is the availability of resources: Dedicated engineering time, Infrastructure (which many OSS authors often cannot afford), Access to knowledge from internal teams like design, QA, and product management. However, this setup often comes with the challenge of dealing with legacy codebases — typically written by developers who may not be familiar with OSS principles. This can lead to inconsistencies in structure, testing, and documentation that require significant refactoring before the project can align with open-source best practices. Navigating The Spectrum: Community vs. Company I like to think of community-driven OSS as being like jazz music—freeform, improvised, and deeply collaborative. In contrast, company-driven OSS resembles an orchestra, with a conductor guiding the performance and ensuring all the pieces fit together seamlessly. The truth is that most OSS projects — if not the vast majority — exist somewhere along this spectrum. For example, TresJS began as a purely community-driven project, but as it matured and gained traction, elements of structured decision-making — more typical of company-driven projects — became necessary to maintain focus and scalability. Together with the core team, we defined a vision and goals for the project to ensure it continued to grow without losing sight of its original purpose. Interestingly, the reverse is also true: Company-driven OSS can benefit significantly from the fast-paced innovation seen in community-driven projects. Many of the improvements I’ve introduced to the Storyblok ecosystem since joining were inspired by ideas first explored in TresJS. For instance, migrating the TresJS ecosystem to pnpm workspaces demonstrated how streamlined dependency management could improve development workflows like playgrounds and e2e — an approach we gradually adapted later for Storyblok’s ecosystem. Similarly, transitioning Storyblok testing from Jest to Vitest, with its improved performance and developer experience, was influenced by how testing is approached in community-driven projects. Likewise, our switch from Prettier to ESLint’s v9 flat configuration with auto-fix helped consolidate linting and formatting into a single workflow, streamlining developer productivity. Even more granular processes, such as modernizing CI workflows, found their way into Storyblok. TresJS’s evolution from a single monolithic release action to granular steps for linting, testing, and building provided a blueprint for enhancing our pipelines at Storyblok. We also adopted continuous release practices inspired by pkg.pr.new, enabling faster delivery of incremental changes and testing package releases in real client projects to gather immediate feedback before merging the PRs. That said, TresJS also benefited from my experiences at Storyblok, which had a more mature and battle-tested ecosystem, particularly in adopting automated processes. For example, we integrated Dependabot to keep dependencies up to date and used auto-merge to reduce manual intervention for minor updates, freeing up contributors’ time for more meaningful work. We also implemented an automatic release pipeline using GitHub Actions, inspired by Storyblok’s workflows, ensuring smoother and more reliable releases for the TresJS ecosystem. The Challenges of Modern OSS Authoring Throughout this article, we’ve touched on several modern OSS challenges, but if one deserves the crown, it’s managing breaking changes and maintaining compatibility. We know how fast the pace of technology is, especially on the web, and users expect libraries and tools to keep up with the latest trends. I’m not the first person to say that hype-driven development can be fun, but it is inherently risky and not your best ally when building reliable, high-performance software — especially in enterprise contexts. Breaking changes exist. That’s why semantic versioning comes into play to make our lives easier. However, it is equally important to balance innovation with stability. This becomes more crucial when introducing new features or refactoring for better performance, breaking existing APIs. One key lesson I’ve learned — particularly during my time at Storyblok — is the importance of clear communication. Changelogs, migration guides, and deprecation warnings are invaluable tools to smoothen the transition for users. A practical example: My first project as a Developer Experience Engineer was introducing @storyblok/richtext, a library for rich-text processing that (at the time of writing) sees around 172k downloads per month. The library was crafted during my time as a DevRel, but transitioning users to it from the previous rich-text implementation across the ecosystem required careful planning. Since the library would become a dependency of the fundamental JS SDK — and from there propagate to all the framework SDKs — together with my manager, we planned a multi-month transition with a retro-compatible period before the major release. This included communication campaigns, thorough documentation, and gradual adoption to minimize disruption. Despite these efforts, mistakes happened — and that’s okay. During the rich-text transition, there were instances where updates didn’t arrive on time or where communication and documentation were temporarily out of sync. This led to confusion within the community, which we addressed by providing timely support on GitHub issues and Discord. These moments served as reminders that even with semantic versioning, modular architectures, and meticulous planning, OSS authoring is never perfect. Mistakes are part of the process. And that takes us to the following point. Conclusion Open-source authoring is a journey of continuous learning. Each misstep offers a chance to improve, and each success reinforces the value of collaboration and experimentation. There’s no “perfect” way to do OSS, and that’s the beauty of it. Every project has its own set of workflows, challenges, and quirks shaped by the community and its contributors. These differences make open source adaptable, dynamic, fun, and, above all, impactful. No matter if you’re building something entirely new or contributing to an existing project, remember that progress, not perfection, is the goal. So, keep contributing, experimenting, and sharing your work. Every pull request, issue, and idea you put forward brings value &mdashp not just to your project but to the broader ecosystem. Happy coding!

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              An Ode To Side Project Time

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                A once-revered perk of some tech workplaces, the status of ‘side project time’ seems to have slipped in recent years. Frederick O’Brien believes it deserves a comeback.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                There seemed to be a hot minute when the tech industry understood the value of idle tinkering and made a point of providing ‘side project time’ as an explicit working perk. The concept endures — I’m lucky enough to work somewhere that has it — but it seems to have been outpaced in recent years by the endless charge toward efficiency. This seems a shame. We can’t optimize our way to quality solutions and original ideas. To try is a self-defeating fantasy. The value of side project time is hard to overstate, and more workplaces should not just provide it but actively encourage it. Here’s why. What Is Side Project Time? Side project time pops up under different names. At the Guardian, it’s 10% time, for example. Whatever the name, it amounts to the same thing: dedicated space and time during working hours for people to work on pet projects, independent learning, and personal development. Google founders Larry Page and Sergey Brin famously highlighted the practice as part of the company’s initial public offering in 2004, writing: “We encourage our employees, in addition to their regular projects, to spend 20% of their time working on what they think will most benefit Google. This empowers them to be more creative and innovative. Many of our significant advances have happened in this manner. For example, AdSense for content and Google News were both prototyped in “20% time.” Most risky projects fizzle, often teaching us something. Others succeed and become attractive businesses.” — Larry Page and Sergey Brin The extent to which Google still supports the practice 20 years on is hazy, and though other tech big hitters talk a good game, it doesn’t seem terribly widespread. The concept threatened to become mainstream for a while but has receded. The Ode There are countless benefits to side project time, both on an individual and corporate level. Whether your priorities are personal growth or making lines, it ought to be on your radar. Individuals On an individual level, side project time frees up people to explore ideas and concepts that interest them. This is good in itself. We all, of course, hope to nurture existing skills and develop new ones in our day-to-day work. Sometimes day to day work provides that. Sometimes it doesn’t. In either case, side project time opens up new avenues for exploration. It is also a space in which the waters can clear. I’ve previously written about the lessons of zen philosophy as they relate to pet project maintenance, with a major aspect being the value of not doing. Getting things done isn’t always the same as making things better. The fog of constant activity — or productivity — can actually keep us from seeing better solutions to problems. Side project time makes for clearer minds to take back with us into the day-to-day grind. Dedicated side project time facilitates personal growth, exploration, and learning. This is obviously good for the individual, but for the project too, because where are the benefits going to be felt? Companies There are a couple of examples of similar company outlooks I’d like to highlight. One is Pixar’s philosophy — as outlined by co-founder Ed Catmull — of protecting ‘ugly babies’, i.e. rough, unformed ideas: “A new thing is hard to define; it’s not attractive, and it requires protection. When I was a researcher at DARPA, I had protection for what was ill-defined. Every new idea in any field needs protection. Pixar is set up to protect our director’s ugly baby.” — Ed Catmull He goes on to point out that they must eventually stand on their own two feet if they are to step out of the sandbox, but that formative time is vital to their development. The mention of DARPA (the Defense Advanced Research Projects Agency), a research and development agency, highlights this outlook, with Bell Labs being one of its shining examples. Its work has received ten Nobel Prizes and five Turing Awards over the years. As journalist Jon Gertner summarised in The Idea Factory: Bell Labs and the Great Age of American Innovation: “It is now received wisdom that innovation and competitiveness are closely linked. But Bell Labs’ history demonstrates that the truth is actually far more complicated…creative environments that foster a rich exchange of ideas are far more important in eliciting new insights than are the forces of competition.” — Jon Gertner It’s a long-term outlook. One Bell employee recalled: “When I first came, there was the philosophy: look, what you’re doing might not be important for ten years or twenty years, but that’s fine, we’ll be there then.” The cynic might say side project time is research and development for companies without the budget allocation. Even if there is some truth to that, I think the former speaks to a more entwined culture. It’s not innovation over here with these people and business as usual over there with those other people. Side project time is also a cultural statement: you and your interests are valuable here. It encourages autonomy and innovation. If we only did OKRs with proven value, then original thinking would inevitably fade away. And let’s be frank: even in purely Machiavellian terms, it benefits employers. You’ll be rewarded with happier, more knowledgeable employees and higher retention. You may even wind up with a surprising new product. Give It A Spin Side project time is a slow burner but an invaluable thing to cultivate. Any readers in a position to try side project time will reap the benefits in time. Some of the best things in life come from idle tinkering. Let people do their thing. Give their ideas space to grow, and they will. And they might just be brilliant. Further Reading “Side Project Programs Can Have Major Benefits for Employers” by Tammy Xu “What made Bell Labs special?” by Andrew Gelman (PDF) “Why Bell Labs Was So Important To Innovation In The 20th Century,” Forbes “Google’s ’20% rule’ shows exactly how much time you should spend learning new skills—and why it works,” Dorie Clark Creativity, Inc. by Ed Catmull

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                On-Device AI: Building Smarter, Faster, And Private Applications

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  Shouldn’t there be a way to keep your apps or project data private and improve performance by reducing server latency? This is what on-device AI is designed to solve. It handles AI processing locally, right on your device, without connecting to the internet and sending data to the cloud. In this article, Joas Pambou explains what on-device AI is, why it’s important, the tools to build this type of technology, and how it can change the way we use technology every day.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  It’s not too far-fetched to say AI is a pretty handy tool that we all rely on for everyday tasks. It handles tasks like recognizing faces, understanding or cloning speech, analyzing large data, and creating personalized app experiences, such as music playlists based on your listening habits or workout plans matched to your progress. But here’s the catch: Where AI tool actually lives and does its work matters a lot. Take self-driving cars, for example. These types of cars need AI to process data from cameras, sensors, and other inputs to make split-second decisions, such as detecting obstacles or adjusting speed for sharp turns. Now, if all that processing depends on the cloud, network latency connection issues could lead to delayed responses or system failures. That’s why the AI should operate directly within the car. This ensures the car responds instantly without needing direct access to the internet. This is what we call On-Device AI (ODAI). Simply put, ODAI means AI does its job right where you are — on your phone, your car, or your wearable device, and so on — without a real need to connect to the cloud or internet in some cases. More precisely, this kind of setup is categorized as Embedded AI (EMAI), where the intelligence is embedded into the device itself. Okay, I mentioned ODAI and then EMAI as a subset that falls under the umbrella of ODAI. However, EMAI is slightly different from other terms you might come across, such as Edge AI, Web AI, and Cloud AI. So, what’s the difference? Here’s a quick breakdown: Edge AI It refers to running AI models directly on devices instead of relying on remote servers or the cloud. A simple example of this is a security camera that can analyze footage right where it is. It processes everything locally and is close to where the data is collected. Embedded AI In this case, AI algorithms are built inside the device or hardware itself, so it functions as if the device has its own mini AI brain. I mentioned self-driving cars earlier — another example is AI-powered drones, which can monitor areas or map terrains. One of the main differences between the two is that EMAI uses dedicated chips integrated with AI models and algorithms to perform intelligent tasks locally. Cloud AI This is when the AI lives and relies on the cloud or remote servers. When you use a language translation app, the app sends the text you want to be translated to a cloud-based server, where the AI processes it and the translation back. The entire operation happens in the cloud, so it requires an internet connection to work. Web AI These are tools or apps that run in your browser or are part of websites or online platforms. You might see product suggestions that match your preferences based on what you’ve looked at or purchased before. However, these tools often rely on AI models hosted in the cloud to analyze data and generate recommendations. The main difference? It’s about where the AI does the work: on your device, nearby, or somewhere far off in the cloud or web. What Makes On-Device AI Useful On-device AI is, first and foremost, about privacy — keeping your data secure and under your control. It processes everything directly on your device, avoiding the need to send personal data to external servers (cloud). So, what exactly makes this technology worth using? Real-Time Processing On-device AI processes data instantly because it doesn’t need to send anything to the cloud. For example, think of a smart doorbell — it recognizes a visitor’s face right away and notifies you. If it had to wait for cloud servers to analyze the image, there’d be a delay, which wouldn’t be practical for quick notifications. Enhanced Privacy and Security Picture this: You are opening an app using voice commands or calling a friend and receiving a summary of the conversation afterward. Your phone processes the audio data locally, and the AI system handles everything directly on your device without the help of external servers. This way, your data stays private, secure, and under your control. Offline Functionality A big win of ODAI is that it doesn’t need the internet to work, which means it can function even in areas with poor or no connectivity. You can take modern GPS navigation systems in a car as an example; they give you turn-by-turn directions with no signal, making sure you still get where you need to go. Reduced Latency ODAI AI skips out the round trip of sending data to the cloud and waiting for a response. This means that when you make a change, like adjusting a setting, the device processes the input immediately, making your experience smoother and more responsive. The Technical Pieces Of The On-Device AI Puzzle At its core, ODAI uses special hardware and efficient model designs to carry out tasks directly on devices like smartphones, smartwatches, and Internet of Things (IoT) gadgets. Thanks to the advances in hardware technology, AI can now work locally, especially for tasks requiring AI-specific computer processing, such as the following: Neural Processing Units (NPUs) These chips are specifically designed for AI and optimized for neural nets, deep learning, and machine learning applications. They can handle large-scale AI training efficiently while consuming minimal power. Graphics Processing Units (GPUs) Known for processing multiple tasks simultaneously, GPUs excel in speeding up AI operations, particularly with massive datasets. Here’s a look at some innovative AI chips in the industry: Product Organization Key Features Spiking Neural Network Chip Indian Institute of Technology Ultra-low power consumption Hierarchical Learning Processor Ceromorphic Alternative transistor structure Intelligent Processing Units (IPUs) Graphcore Multiple products targeting end devices and cloud Katana Edge AI Synaptics Combines vision, motion, and sound detection ET-SoC-1 Chip Esperanto Technology Built on RISC-V for AI and non-AI workloads NeuRRAM CEA–Leti Biologically inspired neuromorphic processor based on resistive RAM (RRAM) These chips or AI accelerators show different ways to make devices more efficient, use less power, and run advanced AI tasks. Techniques For Optimizing AI Models Creating AI models that fit resource-constrained devices often requires combining clever hardware utilization with techniques to make models smaller and more efficient. I’d like to cover a few choice examples of how teams are optimizing AI for increased performance using less energy. Meta’s MobileLLM Meta’s approach to ODAI introduced a model built specifically for smartphones. Instead of scaling traditional models, they designed MobileLLM from scratch to balance efficiency and performance. One key innovation was increasing the number of smaller layers rather than having fewer large ones. This design choice improved the model’s accuracy and speed while keeping it lightweight. You can try out the model either on Hugging Face or using vLLM, a library for LLM inference and serving. Quantization This simplifies a model’s internal calculations by using lower-precision numbers, such as 8-bit integers, instead of 32-bit floating-point numbers. Quantization significantly reduces memory requirements and computation costs, often with minimal impact on model accuracy. Pruning Neural networks contain many weights (connections between neurons), but not all are crucial. Pruning identifies and removes less important weights, resulting in a smaller, faster model without significant accuracy loss. Matrix Decomposition Large matrices are a core component of AI models. Matrix decomposition splits these into smaller matrices, reducing computational complexity while approximating the original model’s behavior. Knowledge Distillation This technique involves training a smaller model (the “student”) to mimic the outputs of a larger, pre-trained model (the “teacher”). The smaller model learns to replicate the teacher’s behavior, achieving similar accuracy while being more efficient. For instance, DistilBERT successfully reduced BERT’s size by 40% while retaining 97% of its performance. Technologies Used For On-Device AI Well, all the model compression techniques and specialized chips are cool because they’re what make ODAI possible. But what’s even more interesting for us as developers is actually putting these tools to work. This section covers some of the key technologies and frameworks that make ODAI accessible. MediaPipe Solutions MediaPipe Solutions is a developer toolkit for adding AI-powered features to apps and devices. It offers cross-platform, customizable tools that are optimized for running AI locally, from real-time video analysis to natural language processing. At the heart of MediaPipe Solutions is MediaPipe Tasks, a core library that lets developers deploy ML solutions with minimal code. It’s designed for platforms like Android, Python, and Web/JavaScript, so you can easily integrate AI into a wide range of applications. MediaPipe also provides various specialized tasks for different AI needs: LLM Inference API This API runs lightweight large language models (LLMs) entirely on-device for tasks like text generation and summarization. It supports several open models like Gemma and external options like Phi-2. Object Detection The tool helps you Identify and locate objects in images or videos, which is ideal for real-time applications like detecting animals, people, or objects right on the device. Image Segmentation MediaPipe can also segment images, such as isolating a person from the background in a video feed, allowing it to separate objects in both single images (like photos) and continuous video streams (like live video or recorded footage). LiteRT LiteRT or Lite Runtime (previously called TensorFlow Lite) is a lightweight and high-performance runtime designed for ODAI. It supports running pre-trained models or converting TensorFlow, PyTorch, and JAX models to a LiteRT-compatible format using AI Edge tools. Model Explorer Model Explorer is a visualization tool that helps you analyze machine learning models and graphs. It simplifies the process of preparing these models for on-device AI deployment, letting you understand the structure of your models and fine-tune them for better performance. You can use Model Explorer locally or in Colab for testing and experimenting. ExecuTorch If you’re familiar with PyTorch, ExecuTorch makes it easy to deploy models to mobile, wearables, and edge devices. It’s part of the PyTorch Edge ecosystem, which supports building AI experiences for edge devices like embedded systems and microcontrollers. Large Language Models For On-Device AI Gemini is a powerful AI model that doesn’t just excel in processing text or images. It can also handle multiple types of data seamlessly. The best part? It’s designed to work right on your devices. For on-device use, there’s Gemini Nano, a lightweight version of the model. It’s built to perform efficiently while keeping everything private. What can Gemini Nano do? Call Notes on Pixel devices This feature creates private summaries and transcripts of conversations. It works entirely on-device, ensuring privacy for everyone involved. Pixel Recorder app With the help of Gemini Nano and AICore, the app provides an on-device summarization feature, making it easy to extract key points from recordings. TalkBack Enhances the accessibility feature on Android phones by providing clear descriptions of images, thanks to Nano’s multimodal capabilities. Note: It’s similar to an application we built using LLaVA in a previous article. Gemini Nano is far from the only language model designed specifically for ODAI. I’ve collected a few others that are worth mentioning: Model Developer Research Paper Octopus v2 NexaAI On-device language model for super agent OpenELM Apple ML Research A significant large language model integrated within iOS to enhance application functionalities Ferret-v2 Apple Ferret-v2 significantly improves upon its predecessor, introducing enhanced visual processing capabilities and an advanced training regimen MiniCPM Tsinghua University A GPT-4V Level Multimodal LLM on Your Phone Phi-3 Microsoft Phi-3 Technical Report: A Highly Capable Language Model Locally on Your Phone The Trade-Offs of Using On-Device AI Building AI into devices can be exciting and practical, but it’s not without its challenges. While you may get a lightweight, private solution for your app, there are a few compromises along the way. Here’s a look at some of them: Limited Resources Phones, wearables, and similar devices don’t have the same computing power as larger machines. This means AI models must fit within limited storage and memory while running efficiently. Additionally, running AI can drain the battery, so the models need to be optimized to balance power usage and performance. Data and Updates AI in devices like drones, self-driving cars, and other similar devices process data quickly, using sensors or lidar to make decisions. However, these models or the system itself don’t usually get real-time updates or additional training unless they are connected to the cloud. Without these updates and regular model training, the system may struggle with new situations. Biases Biases in training data are a common challenge in AI, and ODAI models are no exception. These biases can lead to unfair decisions or errors, like misidentifying people. For ODAI, keeping these models fair and reliable means not only addressing these biases during training but also ensuring the solutions work efficiently within the device’s constraints. These aren't the only challenges of on-device AI. It's still a new and growing technology, and the small number of professionals in the field makes it harder to implement. Conclusion Choosing between on-device and cloud-based AI comes down to what your application needs most. Here’s a quick comparison to make things clear: Aspect On-Device AI Cloud-Based AI Privacy Data stays on the device, ensuring privacy. Data is sent to the cloud, raising potential privacy concerns. Latency Processes instantly with no delay. Relies on internet speed, which can introduce delays. Connectivity Works offline, making it reliable in any setting. Requires a stable internet connection. Processing Power Limited by device hardware. Leverages the power of cloud servers for complex tasks. Cost No ongoing server expenses. Can incur continuous cloud infrastructure costs. For apps that need fast processing and strong privacy, ODAI is the way to go. On the other hand, cloud-based AI is better when you need more computing power and frequent updates. The choice depends on your project’s needs and what matters most to you.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  The Role Of Illustration Style In Visual Storytelling

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    How do we determine the most suitable illustration style? How should illustrations complement and reflect your corporate identity? What will resonate most with your target audience? And regarding the content, what type of illustration would best enhance it, and how would it work for the age range it is primarily for? Thomas Bohm shares insightful examples and discusses the key qualities of effective illustrations, emphasizing the importance of understanding your audience.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    Illustration has been used for 10,000 years. One of the first ever recorded drawings was of a hand silhouette found in Spain, that is more than 66,000 years old. Fast forward to the introduction of the internet, around 1997, illustration has gradually increased in use. Popular examples of this are Google’s daily doodles and the Red Bull energy drink, both of which use funny cartoon illustrations and animations to great effect. Typically, illustration was done using pencils, chalk, pens, etchings, and paints. But now everything is possible — you can do both analog and digital or mixed media styles. As an example, although photography might be the most popular method to communicate visuals, it is not automatically the best default solution. Illustration offers a wider range of styles that help companies engage and communicate with their audience. Good illustrations create a mood and bring to life ideas and concepts from the text. To put it another way, visualisation. Good illustrations can also help give life to information in a better way than just using text, numbers, or tables. How do we determine what kind of illustration or style would be best? How should illustration complement or echo your corporate identity? What will your main audience prefer? What about the content, what would suit and highlight the content best, and how would it work for the age range it is primarily for? Before we dive into the examples, let’s discuss the qualities of good illustration and the importance of understanding your audience. The rubric below will help you make good choices for your audience’s benefit. What Makes A Good Illustration Visualises something from the content (something that does not exist or has been described but not visualised). Must be aesthetically pleasing, interesting, and stimulating to look at (needs to have qualities and harmonies between colour, elements, proportions, and subject matter). Must have a feel, mood, dramatic edge, or attitude (needs to create a feeling and describe or bring to life an environment). The illustration should enhance and bring to life what is described in text and word form. Explains or unpacks what is written in any surrounding text and makes it come to life in an unusual and useful way (the illustration should complement and illuminate the content so readers better understand the content). Just look at what we are more often than not presented with. The importance of knowing about different audiences It is really important to know and consider different audiences. Not all of us are the same and have the same physical, cognitive, education, or resources. Our writing, designs, and illustrations need to take into account users’ make-up and capabilities. There are some common categories of audiences: Child, Teenager, Middle-aged, Ageing, Prefer a certain style (goth, retro, modern, old fashioned, sporty, branded). Below are interesting examples of illustrations, in no particular order, that show how different styles communicate and echo different qualities and affect mood and tone. Watercolour Good for formal, classy, and sophisticated imagery that also lends itself to imaginative expression. It is a great example of texture and light that delivers a really humane and personal feel that you would not get automatically by using software. Strengths Feeling, emotion, and sense of depth and texture. Drawing With Real-life objects A great option for highly abstract concepts and compositions with a funny, unusual, and unreal aspect. You can do some really striking and clever stuff with this style to engage readers in your content. Strengths Conceptual play. Surreal Photomontage Perfect for abstract hybrid illustration and photo illustration with a surreal fantasy aspect. This is a great example of merging different imagery together to create a really dramatic, scary, and visually arresting new image that fits the musician’s work as well. Strengths Conceptual mixing and merging, leading to new unseen imagery. Cartoon Well-suited for showing fun or humorous aspects, creating concepts with loads of wit and cleverness. New messages and forms of communication can be created with this style. Strengths Conceptual. Cartoon With Block Colour Works well for showing fun, quirky, or humorous aspects and concepts, often with loads of wit and cleverness. The simplicity of style can be quite good for people who struggle with more advanced imagery concepts, making it quite accessible. Strengths Simplicity and unclutteredness. Clean Vector Designed for clean and clear illustrations that are all-encompassing and durable. Due to the nature of this illustration style, it works quite well for a wide range of people as it is not overly stylistic in one direction or another. Strengths Realism, conceptual, and widely pleasing. Textured Vintage Clean Vector Best suited for imagining rustic imagery, echoing a vintage feel. This a great example of how texture and non-cleanliness can create and enhance the feeling of the imagery; it is very Western and old-fashioned, perfect for the core meaning of the illustration. Strengths Aged feeling and rough impression. Pictogram Highly effective for clean, legible, quickly recognizable imagery and concepts, especially at small sizes as well. It is no surprise that many pictograms are to be seen in quick viewing environments such as airports and show imagery that has to work for a wide range of people. Strengths Legibility, speed of comprehension (accessibility). Abstract Geometric A great option for visually attractive and abstract imagery and concepts. This style lends itself to much customising and experimentation from the illustrator, giving some really cool and visually striking results. Strengths Visual stimulation and curiosity. Lithography Etching Ideal for imagery that has an old, historic, and traditional feel. Has a great feel achieved through sketchy markings, etchings, and a greyscale colour palette. You would not automatically get this from software, but given the right context or maybe an unusual juxtaposed context (like the clash against a modern, clean, fashionable corporate identity), it could work really well. Strengths Realism and old tradition. 3D gradient It serves as a great choice for highly realistic illustration with a friendly, widely accessible character element. This style is not overly stylistic and lends itself to being accepted by a wider range of people. Strengths Widely acceptable and appropriate. Sci-fi Comic Book And Pop Art It’s especially useful for high-impact, bright, animated, and colourful concepts. Some really cool, almost animated graphic communication can be created with this style, which can also be put to much humorous use. The boldness and in-your-face style promote visual engagement. Strengths Animation. Tatoo Well-suited for bold block-coloured silhouettes and imagery. It is so bold and impactful, and there is still loads of detail there, creating a really cool and sharp illustration. The illustration works well in black and white and would be further enhanced with colour. Strengths Directness and clarity. Pencil Perfect for humane, detailed imagery with plenty of feeling and character. The sketchy style highlights unusual details and lends itself to an imaginative feeling and imagery. Strengths Humane and detailed imaginative feeling. Gradient Especially useful for highly imaginative and fantasy imagery. By using gradients and a light-to-dark color palette, the imagery really has depth and says, ‘Take me away on a journey.’ Strengths Fantasy (through depth of colour) and clean feeling. Charcoal It makes an excellent option for giving illustration a humane and tangible feel, with echoes of old historical illustrations. The murky black-and-white illustration really has an atmosphere to it. Strengths Humane and detailed feeling. Woodcut It offers great value for block silhouette imagery that has presence, sharpness, and impact. Is colour even needed? The black against the light background goes a long way to communicating the imagery. Strengths Striking and clear. Fashion A great option for imagery that has motion and flare to it, with a slight feminine feel. No wonder this style of illustration is used for fashion illustrations, great for expressing lines and colours with motion, and has a real fashion runway flare. Strengths Motion and expressive flare. Caricature Ideal for humorous imagery and illustration with a graphic edge and clarity. The layering of light and dark elements really creates an illustration with depth, perfect for playing with the detail of the character, not something you would automatically get from a clean vector illustration. It has received more thought and attention than clean vector illustration typically does. Strengths Detail and humour. Paint It serves as a great choice for traditional romantic imagery that has loads of detail, texture, and depth of feeling. The rose flowers are a good example of this illustration style because they have so much detail and colour shades. Strengths Tradition and emotions. Chalk Well-suited for highly sketchy imagery to make something an idea or working concept. The white lines against the black background have an almost animated effect and give the illustrations real movement and life. This style is a good example of using pure lines in illustration but to great effect. Strengths Hand-realised and animation. Illustration Sample Card How To Start Doing Illustration There are plenty of options, such as using pencils, chalk, pens, etchings, and paints, then possibly scanning in. You can also use software like Illustrator, Photoshop, Procreate, Corel Painter, Sketch, Inkscape, or Figma. But no matter what tools you choose, there’s one essential ingredient you’ll always need, and that is a mind and vision for illustration. Recommended Resources Association of Illustrators “20 Best Illustration Agents In The UK, And The Awesome Illustrators They Represent,” Tom May It’s Nice That Behance Illustration

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    Solo Development: Learning To Let Go Of Perfection

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      The best and worst thing about solo development is the “solo” part. There’s a lot of freedom in working alone, and that freedom can be inspiring, but it can also become a debilitating hindrance to productivity and progress. Victor Ayomipo shares his personal lessons on what it takes to navigate solo development and build the “right” app.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      As expected from anyone who has ever tried building anything solo, my goal was not to build an app but the app — the one app that’s so good you wonder how you ever survived without it. I had everything in place: wireframes, a to-do list, project structure — you name it. Then I started building. Just not the product. I started with the landing page for it, which took me four days, and I hadn’t even touched the app’s core features yet. The idea itself was so good I had to start marketing it right away! I found myself making every detail perfect: every color, shadow, gradient, font size, margin, and padding had to be spot on. I don’t even want to say how long the logo took. Spoiler: No one cares about your logo. Why did I get so stuck on something that was never even part of the core app I wanted so badly to build? Why wasn’t I nagging myself to move on when I clearly needed to? The reality of solo development is that there is no one to tell you when to stop or simply say, “Yo, this is good enough! Move on.“ Most users don’t care whether a login button is yellow or green. What they want (and need) is a button that works and solves their problem when clicking it. Test Early And Often Unnecessary tweaks, indecisive UI decisions, and perfectionism are the core reasons I spend more time on things than necessary. Like most solo developers, I also started with the hope of pushing out builds with the efficiency of a large-scale team. But it is easier said than done. When building solo, you start coding, then you maybe notice a design flaw, and you switch to fixing it, then a bug appears, and you try fixing that, and voilà — the day is gone. There comes a time when it hits you that, “You know what? It’s time to build messy.” That’s when good intentions of project and product management go out the window, and that’s when I find myself working by the seat of my pants rather than plowing forward with defined goals and actionable tasks that are based on good UI/UX principles, like storyboards, user personas, and basic prioritization. This realization is something you have to experience to grasp fully. The trick I’ve learned is to focus on getting something out there for people to see and then work on actual feedback. In other words, It’s more important to get the idea out there and iterate on it than reaching for perfection right out of the gate. Because guess what? Even if you have the greatest app idea in the world, you’re never going to make it perfect until you start receiving feedback on it. You’re no mind reader — as much as we all want to be one — and some insights (often the most relevant) can only be received through real user feedback and analytics. Sure, your early assumptions may be correct, but how do you know until you ship them and start evaluating them? Nowadays, I like to tell others (and myself) to work from hypotheses instead of absolutes. Make an assertion, describe how you intend to test it, and then ship it. With that, you can gather relevant insights that you can use to get closer to perfection — whatever that is. Strength In Recognizing Weakness Let’s be real: Building a full application on your own is not an easy feat. I’d say it’s like trying to build a house by yourself; it seems doable, but the reality is that it takes a lot more hands than the ones you have to make it happen. And not only to make it happen but to make it happen well. There’s only so much one person can do, and admitting your strengths and weaknesses up-front will serve you well by avoiding the trap that you can do it all alone. I once attempted to build a project management app alone. I knew it might be difficult, but I was confident. Within a few days, this “simple” project grew legs and expanded with new features like team collaboration, analytics, time tracking, and custom reports being added, many of which I was super excited to make. Building a full app takes a lot of time. Think about it; you’re doing the work of a team all alone without any help. There’s no one to provide you with design assets, content, or back-end development. No stakeholder to “swoop and poop” on your ideas (which might be a good thing). Every decision, every line of code, and every design element is 100% on you alone. It is technically possible to build a full-featured app solo, but when you think about it, there’s a reason why the concept of MVP exists. Take Instagram, for example; it wasn’t launched with reels, stories, creator’s insights, and so on. It started with one simple thing: photo sharing. All I’m trying to say is start small, launch, and let users guide the evolution of the product. And if you can recruit more hands to help, that would be even better. Just remember to leverage your strengths and reinforce your weaknesses by leaning on other people’s strengths. Yes, Think Like an MVP The concept of a minimum viable product (MVP) has always been fascinating to me. In its simplest form, it means building the basic version of your idea that technically works and getting it in front of users. Yes, this is such a straightforward and widely distributed tip, but it’s still one of the hardest principles for solo developers to follow, particularly for me. I mentioned earlier that my “genius” app idea grew legs. And lots of them. I had more ideas than I knew what to do with, and I hadn’t even written a reasonable amount of code! Sure, this app could be enhanced to support face ID, dark mode, advanced security, real-time results, and a bunch of other features. But all these could take months of development for an app that you’re not even certain users want. I’ve learned to ask myself: “What would this project look like if it was easy to build?”. It’s so surreal how the answer almost always aligns with what users want. If you can distill your grand idea into a single indispensable idea that does one or two things extremely well, I think you’ll find — as I have — that the final result is laser-focused on solving real user problems. Ship the simplest version first. Dark mode can wait. All you need is a well-defined idea, a hypothesis to test, and a functional prototype to validate that hypothesis; anything else is probably noise. Handle Imperfection Gracefully You may have heard about the “Ship it Fast” approach to development and instantly recognize the parallels between it and what I’ve discussed so far. In a sense, “Ship it Fast” is ultimately another way of describing an MVP: get the idea out fast and iterate on it just as quickly. Some might disagree with the ship-fast approach and consider it reckless and unprofessional, which is understandable because, as developers, we care deeply about the quality of our work. However, The ship-fast mentality is not to ignore quality but to push something out ASAP and learn from real user experiences. Ship it now — perfect it later. That’s why I like to tell other developers that shipping an MVP is the safest, most professional way to approach development. It forces you to stay in scope and on task without succumbing to your whimsies. I even go so far as to make myself swear an “Oath of Focus” at the start of every project. I, Vayo, hereby solemnly swear (with one hand on this design blueprint) to make no changes, no additions, and no extra features until this app is fully built in all its MVP glory. I pledge to avoid the temptations of endless tweaking and the thoughts of “just one more feature.” Only when a completed prototype is achieved will I consider any new features, enhancements, or tweaks. Signed, Vayo, Keeper of the MVP Remember, there’s no one there to hold you accountable when you develop on your own. Taking a brief moment to pause and accepting that my first version won’t be flawless helps put me in the right headspace early in the project. Prioritize What Matters I have noticed that no matter what I build, there’s always going to be bugs. Always. If Google still has bugs in the Google Notes app, trust me, then it’s fine for a solo developer to accept that bugs will always be a part of any project. Look at flaky tests. For instance, you could run a test over 1,000 times and get all greens, and then the next day, you run the same test, an error shows. It’s just the nature of software development. And for the case of endlessly adding features, it never ends either. There’s always going to be a new feature that you’re excited about. The challenge is to curb some of that enthusiasm and shelve it responsibly for a later time when it makes sense to work on it. I’ve learned to categorize bugs and features into two types: intrusive and non-intrusive. Intrusive are those things that prevent projects from functioning properly until fixed, like crashes and serious errors. The non-intrusive items are silent ones. Sure, they should be fixed, but the product will work just fine and won’t prevent users from getting value if they aren’t addressed right away. You may want to categorize your bugs and features in other ways, and I’ve seen plenty of other examples, including: High value, low value; High effort, low effort; High-cost, low-cost; Need to have, nice to have. I’ve even seen developers and teams use these categorizations to create some fancy priority “score” that considers each category. Whatever it is that helps you stay focused and on-task is going to be the right approach for you more than what specific category you use. Live With Your Stack Here’s a classic conundrum in development circles: Should I use React? Or NextJS? Or wait, how about Vue? I heard it’s more optimized. But hold on, I read that React Redux is dead and that Zustand is the new hot tool. And just like that, you’ve spent an entire day thinking about nothing but the tech stack you’re using to build the darn thing. We all know that an average user could care less about the tech stack under the hood. Go ahead and ask your mom what tech stack WhatsApp is built on, and let me know what she says. Most times, it’s just us who obsesses about tech stacks, and that usually only happens when we’re asked to check under the hood. I have come to accept that there will always be new tech stacks released every single day with the promise of 50% performance and 10% less code. That new tool might scale better, but do I actually have a scaling problem with my current number of zero users? Probably not. My advice: Pick the tools you work with best and stick to those tools until they start working against you. There’s no use fighting something early if something you already know and use gets the job done. Basically, don’t prematurely optimize or constantly chase the latest shiny object. Do Design Before The First Line of Code I know lots of solo developers out there suck at design, and I’m probably among the top 50. My design process has traditionally been to open VS Code, create a new project, and start building the idea in whatever way comes to mind. No design assets, comps, or wireframes to work with — just pure, unstructured improvisation. That’s not a good idea, and it’s a habit I’m actively trying to break. These days, I make sure to have a blueprint of what I’m building before I start writing code. Once I have that, I make sure to follow through and not change anything to respect my “Oath of Focus.” I like how many teams call comps and wireframes “project artifacts.” They are pieces of evidence that provide a source of truth for how something looks and works. You might be the sort of person who works better with sets of requirements, and that’s totally fine. But having some sort of documentation that you can point back to in your work is like having a turn-by-turn navigation on a long road trip — it’s indispensable for getting where you need to go. And what if you’re like me and don’t pride yourself on being the best designer? That’s another opportunity to admit your weaknesses up-front and recruit help from someone with those strengths. That way, you can articulate the goal and focus on what you’re good at. Give Yourself Timelines Personally, without deadlines, I’m almost unstoppable at procrastinating. I’ve started setting time limits when building any project, as it helps with procrastination and makes sure something is pushed out at a specified time. Although this won’t work without accountability, I feel the two work hand in hand. I set a 2–3 week deadline to build a project. And no matter what, as soon as that time is up, I must post or share the work in its current state on my socials. Because of this, I’m not in my comfort zone anymore because I won’t want to share a half-baked project with the public; I’m conditioned to work faster and get it all done. It’s interesting to see the length of time you can go if you can trick your brain. I realize that this is an extreme constraint, and it may not work for you. I’m just the kind of person who needs to know what my boundaries are. Setting deadlines and respecting them makes me a more disciplined developer. More than that, it makes me work efficiently because I stop overthinking things when I know I have a fixed amount of time, and that leads to faster builds. Conclusion The best and worst thing about solo development is the “solo” part. There’s a lot of freedom in working alone, and that freedom can be inspiring. However, all that freedom can be intoxicating, and if left unchecked, it becomes a debilitating hindrance to productivity and progress. That’s a good reason why solo development isn’t for everyone. Some folks will respond a lot better to a team environment. But if you are a solo developer, then I hope my personal experiences are helpful to you. I’ve had to look hard at myself in the mirror many days to come to realize that I am not a perfect developer who can build the “perfect” app alone. It takes planning, discipline, and humility to make anything, especially the right app that does exactly the right thing. Ideas are cheap and easy, but stepping out of our freedom and adding our own constraints based on progress over perfection is the secret sauce that keeps us moving and spending our time on those essential things. Further Reading On SmashingMag “What’s The Perfect Design Process?,” Vitaly Friedman “Design Under Constraints: Challenges, Opportunities, And Practical Strategies,” Paul Boag “Improving The Double Diamond Design Process,” Andy Budd “Unexpected Learnings From Coding Artwork Every Day For Five Years,” Saskia Freeke

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      Tight Mode: Why Browsers Produce Different Performance Results

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        We know that browsers do all sorts of different things under the hood. One of those things is the way they not only *fetch* resources like images and scripts from the server but how they [prioritize those resources](https://www.debugbear.com/blog/request-priorities?utm_campaign=sm-7). Chrome and Safari have implemented a “Tight Mode” that constrains which resources are loaded and in what order, but they each take drastically different approaches to it. With so little information about Tight Mode available, this article attempts a high-level explanation of what it is, what triggers it, and how it is treated differently in major browsers.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        This article is a sponsored by DebugBear I was chatting with DebugBear’s Matt Zeunert and, in the process, he casually mentioned this thing called Tight Mode when describing how browsers fetch and prioritize resources. I wanted to nod along like I knew what he was talking about but ultimately had to ask: What the heck is “Tight” mode? What I got back were two artifacts, one of them being the following video of Akamai web performance expert Robin Marx speaking at We Love Speed in France a few weeks ago: Tight Mode discriminates resources, taking anything and everything marked as High and Medium priority. Everything else is constrained and left on the outside, looking in until the body is firmly attached to the document, signaling that blocking scripts have been executed. It’s at that point that resources marked with Low priority are allowed in the door during the second phase of loading. There’s a big caveat to that, but we’ll get there. The important thing to note is that… Chrome And Safari Enforce Tight Mode Yes, both Chrome and Safari have some working form of Tight Mode running in the background. That last image illustrates Chrome’s Tight Mode. Let’s look at Safari’s next and compare the two. Look at that! Safari discriminates High-priority resources in its initial fetch, just like Chrome, but we get wildly different loading behavior between the two browsers. Notice how Safari appears to exclude the first five PNG images marked with Medium priority where Chrome allows them. In other words, Safari makes all Medium- and Low-priority resources wait in line until all High-priority items are done loading, even though we’re working with the exact same HTML. You might say that Safari’s behavior makes the most sense, as you can see in that last image that Chrome seemingly excludes some High-priority resources out of Tight Mode. There’s clearly some tomfoolery happening there that we’ll get to. Where’s Firefox in all this? It doesn’t take any extra tightening measures when evaluating the priority of the resources on a page. We might consider this the “classic” waterfall approach to fetching and loading resources. Chrome And Safari Trigger Tight Mode Differently Robin makes this clear as day in his talk. Chrome and Safari are both Tight Mode proponents, yet trigger it under differing circumstances that we can outline like this: Chrome Safari Tight Mode triggered While blocking JS in the <head> is busy. While blocking JS or CSS anywhere is busy. Notice that Chrome only looks at the document <head> when prioritizing resources, and only when it involves JavaScript. Safari, meanwhile, also looks at JavaScript, but CSS as well, and anywhere those things might be located in the document — regardless of whether it’s in the <head> or <body>. That helps explain why Chrome excludes images marked as High priority in Figure 2 from its Tight Mode implementation — it only cares about JavaScript in this context. So, even if Chrome encounters a script file with fetchpriority="high" in the document body, the file is not considered a “High” priority and it will be loaded after the rest of the items. Safari, meanwhile, honors fetchpriority anywhere in the document. This helps explain why Chrome leaves two scripts on the table, so to speak, in Figure 2, while Safari appears to load them during Tight Mode. That’s not to say Safari isn’t doing anything weird in its process. Given the following markup: <head> <!-- two high-priority scripts --> <script src="script-1.js"></script> <script src="script-1.js"></script> <!-- two low-priority scripts --> <script src="script-3.js" defer></script> <script src="script-4.js" defer></script> </head> <body> <!-- five low-priority scripts --> <img src="image-1.jpg"> <img src="image-2.jpg"> <img src="image-3.jpg"> <img src="image-4.jpg"> <img src="image-5.jpg"> </body> …you might expect that Safari would delay the two Low-priority scripts in the <head> until the five images in the <body> are downloaded. But that’s not the case. Instead, Safari loads those two scripts during its version of Tight Mode. Chrome And Safari Exceptions I mentioned earlier that Low-priority resources are loaded in during the second phase of loading after Tight Mode has been completed. But I also mentioned that there’s a big caveat to that behavior. Let’s touch on that now. According to Patrick’s article, we know that Tight Mode is “the initial phase and constraints loading lower-priority resources until the body is attached to the document (essentially, after all blocking scripts in the head have been executed).” But there’s a second part to that definition that I left out: “In tight mode, low-priority resources are only loaded if there are less than two in-flight requests at the time that they are discovered.” A-ha! So, there is a way for low-priority resources to load in Tight Mode. It’s when there are less than two “in-flight” requests happening when they’re detected. Wait, what does “in-flight” even mean? That’s what’s meant by less than two High- or Medium-priority items being requested. Robin demonstrates this by comparing Chrome to Safari under the same conditions, where there are only two High-priority scripts and ten regular images in the mix: <head> <!-- two high-priority scripts --> <script src="script-1.js"></script> <script src="script-1.js"></script> </head> <body> <!-- ten low-priority images --> <img src="image-1.jpg"> <img src="image-2.jpg"> <img src="image-3.jpg"> <img src="image-4.jpg"> <img src="image-5.jpg"> <!-- rest of images --> <img src="image-10.jpg"> </body> Let’s look at what Safari does first because it’s the most straightforward approach: Nothing tricky about that, right? The two High-priority scripts are downloaded first and the 10 images flow in right after. Now let’s look at Chrome: We have the two High-priority scripts loaded first, as expected. But then Chrome decides to let in the first five images with Medium priority, then excludes the last five images with Low priority. What. The. Heck. The reason is a noble one: Chrome wants to load the first five images because, presumably, the Largest Contentful Paint (LCP) is often going to be one of those images and Chrome is hedging bets that the web will be faster overall if it automatically handles some of that logic. Again, it’s a noble line of reasoning, even if it isn’t going to be 100% accurate. It does muddy the waters, though, and makes understanding Tight Mode a lot harder when we see Medium- and Low-priority items treated as High-priority citizens. Even muddier is that Chrome appears to only accept up to two Medium-priority resources in this discriminatory process. The rest are marked with Low priority. That’s what we mean by “less than two in-flight requests.” If Chrome sees that only one or two items are entering Tight Mode, then it automatically prioritizes up to the first five non-critical images as an LCP optimization effort. Truth be told, Safari does something similar, but in a different context. Instead of accepting Low-priority items when there are less than two in-flight requests, Safari accepts both Medium and Low priority in Tight Mode and from anywhere in the document regardless of whether they are located in the <head> or not. The exception is any asynchronous or deferred script because, as we saw earlier, those get loaded right away anyway. How To Manipulate Tight Mode This might make for a great follow-up article, but this is where I’ll refer you directly to Robin’s video because his first-person research is worth consuming directly. But here’s the gist: We have these high-level features that can help influence priority, including resource hints (i.e., preload and preconnect), the Fetch Priority API, and lazy-loading techniques. We can indicate fetchpriority="high" and fetchpriority="low" on items. <img src="lcp-image.jpg" fetchpriority="high"> <link rel="preload" href="defer.js" as="script" fetchpriority="low"> Using fetchpriority="high" is one way we can get items lower in the source included in Tight Mode. Using fetchpriority="low is one way we can get items higher in the source excluded from Tight Mode. For Chrome, this works on images, asynchronous/deferred scripts, and scripts located at the bottom of the <body>. For Safari, this only works on images. Again, watch Robin’s talk for the full story starting around the 28:32 marker. That’s Tight… Mode It’s bonkers to me that there is so little information about Tight Mode floating around the web. I would expect something like this to be well-documented somewhere, certainly over at Chrome Developers or somewhere similar, but all we have is a lightweight Google Doc and a thorough presentation to paint a picture of how two of the three major browsers fetch and prioritize resources. Let me know if you have additional information that you’ve either published or found — I’d love to include them in the discussion.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        Lesser Known Uses Of Better Known Attributes

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          HTML attributes are like little instructions that we add to the markup of elements to make them do certain things or behave in certain ways. For example, most of us know that the `target` attribute with a value of `_blank` opens the link in a new tab or window. But did you know that you can use it on the `form` element, too? John Rhea presents several lesser-known uses for common HTML attributes.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          The list of attributes available in HTML is long and well-documented. Even if you haven’t memorized them (and there’s totally nothing wrong with an author… er… random person off the street, who has), there are a bunch of places where HTML attributes you’re familiar with will have different or more specific jobs. Let’s take a look. name You may have heard of the name attribute, giving a name/label to information sent through a form. And more specifically you may have used it to bring together a set of radio buttons, but you can also use it with the details element to have only one of a set of accordions open at a time. Like if you have more than one refrigerator in the office at work, any respectable person would only open one door at a time. Right, Bob? <details name="office-kitchen"> <summary>Refrigerator 1</summary> Lunches, condiments, yogurt et al. </details> <details name="office-kitchen"> <summary>Refrigerator 2</summary> More Lunches, leftovers from client meeting, stray cans of off-brand soda et al. </details> <details name="office-kitchen"> <summary>Refrigerator 3</summary> Cookie dough someone bought from somebody’s child’s fundraiser, expired milk, unidentifiable meat et al. </details> See the Pen Name [forked] by Undead Institute. title You’ve probably heard of the universal attribute title. It’s typically thought of as the built-in tooltip text, but three elements have special semantics for the title attribute: input and the rarely used gems, the definition (dfn) element, and the abbreviation (abbr) element. If you’re using a pattern attribute on an input to provide some regex-based error correction, then you should definitely tell the user how to meet the criteria you’re using. The title attribute can be used both as a tooltip and as the message shown when the user doesn’t meet that criteria. <form method="post" action="#"> <label>Who took my <em>well labeled</em> yogurt from the company fridge? I know it was you, Bob.<br> <input type="text" pattern="Bob [A-Za-z].+" title="There are many Bobs. The only question is which one it was. Please limit your answers to Bob and his/her last name."> </label><br> <button type="submit">Submit</submit> </form> See the Pen Title - Input [forked] by Undead Institute. For a dfn element, if you use the title attribute, then it has to include the term being defined. dfn should still have text in it, but it can be an abbreviation or a different form of the term. <p><dfn title="Office Yogurt Thief">OYG</dfn>’s are a pox on humanity. Stealing yogurts from the office fridge even when they are labeled.</p> See the Pen Title - dfn [forked] by Undead Institute. A title on an abbr element not only sets the tooltip but explicitly has the expansion of the abbreviation or acronym. As it says in the spec: "The [title] attribute, if specified, must contain an expansion of the abbreviation, and nothing else." That’s the specification’s equivalent of threatening a mafia hit if you aren’t careful with your title attributes. You have been warned, Bob. When dealing with a suspected yogurt thief, we must create a <abbr title="Human Resources Special Task Force on Yogurt Theft">HRSTFYT</abbr> to deal with the problem. See the Pen Title - abbr [forked] by Undead Institute. value The value attribute is well known for setting default values on inputs, but you can also use it on a list item (li) within an ordered list (ol) to change the number of that item and all that follow it. It only takes integers, but you can use it no matter what type of ordered list you use (numeric, alphabetical, or Roman numerals). <h1>Favorite Co-workers</h1> <ol> <li>Tina</li> <li>Keesha</li> <li>Carlos</li> <li>Jamal</li> <li>Scott</li> <li value="37">Bob</li> <li>Bobbie</li> <li>Bobby</li> <li>"Rob"</li> </ol> See the Pen Value [forked] by Undead Institute. datetime You might have used a datetime attribute on a time element to provide a machine-readable format of the time and/or date represented in the time element’s text: <time datetime="2024-12-09">Dec. 12, 2024</time> The same attribute can also be used with the ins and del elements (used for notating an addition/insertion and deletion of content, respectively). The datetime attribute on ins and del provides a machine-readable date (and optionally a time) for when the change was made. You can show it to the visitor if you like, but it’s mainly intended for private use. Check out the edits of the original version of an earlier example: When dealing with a <ins datetime="2024-11-17">suspected</ins> yogurt thief <del datetime="2024-11-17">, like Bob,</del> we must create a <abbr title="Human Resources Special Task Force on Yogurt Theft">HRSTFYT</abbr> to deal with <del datetime="2024-11-17">Bob</del> <ins datetime="2024-11-17">the problem</ins>. See the Pen Datetime [forked] by Undead Institute. As an added note, screenreaders do not announce the datetime attribute in this context. cite Sticking with our oft-neglected friends ins and del, the cite attribute that you use on blockquote and q elements to provide a URL of the source of the quotation can also be used on ins and del to provide the URL of a document explaining the changes. When dealing with a <ins datetime="2024-11-17" cite="https://codepen.io/undeadinstitute/full/VYZeaZm">suspected</ins> yogurt thief <del datetime="2024-11-17" cite="https://codepen.io/undeadinstitute/full/VYZeaZm">, like Bob,</del> we must create a <abbr title="Human Resources Special Task Force on Yogurt Theft">HRSTFYT</abbr> to deal with <del datetime="2024-11-17" cite="https://codepen.io/undeadinstitute/full/VYZeaZm">Bob</del> <ins datetime="2024-11-17" cite="https://codepen.io/undeadinstitute/full/VYZeaZm">the problem</ins>. See the Pen Cite [forked] by Undead Institute. Again, these dates are not announced in assistive tech, like screen readers. multiple You probably know the multiple attribute as that more-than-meets-the-eye attribute that transforms a dropdown menu into a multi-select box, like a co-worker who lets you choose two donuts from the box. (I’m lookin’ at you, Tina.) But it has two other uses as well. You can add it to both a file input and an email input to accept multiple files and emails, respectively. <form method="post" action="#"> <label>Upload complaint forms (about Bob) <input type="file" multiple> </label><br> <label>Email all of Bob’s bosses: <input type="email" multiple></label><br> <button type="submit">Submit</submit> </form> Just be sure that the emails are comma-separated. See the Pen Multiple [forked] by Undead Institute. for In your travels across the internet, you’ve probably come across the for attribute when it’s used to associate a label element with a form field (input, select, textarea, etc.), but you can also use it to explicitly associate the elements of a calculation with an output element. Unlike a label-input relationship, which is a one-to-one relationship (i.e., one label for one field), the for attribute used on an output can hold an unordered, space-separated list of IDs of the fields that contributed to the calculation. <form method="post" action="#" id="comeuppance"> <fieldset><legend>Defendant name</legend> <label>First Name: <input name="fname" type="text"></label> <label>Last Name: <input name="lname" type="text"></label> </fieldset> <label>Number of yogurts stolen (unlabeled): <input name="numunlbld" id="numstolen-unlbld" type="number"> </label> * <label>Unlabeled Multiplier: <input name="multiunlbld" id="multi-unlbld" type="number" value="0.5"> </label> + <label>Number of yogurts stolen (labeled): <input name="numlbld" id="numstolen-lbld" type="number"> </label> * <label>Labeled Multiplier: <input name="multilbld" id="multi-lbld" type="number" value="1.5"> </label> = <label>Suggested prison term (in years): <output id="answer" for="numstolen-unlbld numstolen-lbld multi-unlbld multi-lbld"></output> </label> </form> See the Pen For [forked] by Undead Institute. target Just like you can use a target attribute to open a link in a new tab/window, you can use the same target attribute and value _blank to have a form open the response in a new tab/window. <form method="post" action="#" id="comeuppance" target="_blank"> [...] </form> disabled You may have used the disabled attribute to knock out an individual form field, but you can also use it to disable every descendant of a fieldset element. No matter what HR says and its innocent-until-proven-guilty ethos, we all know Bob did it. Don’t we? <form method="post" action="#" id="comeuppance"> <fieldset disabled><legend>Defendant name</legend> <label>First Name: <input name="fname" type="text" value="Bob"></label> <label>Last Name: <input name="lname" type="text" value="McBobberson"></label> </fieldset> [...] </form> See the Pen Disabled [forked] by Undead Institute. Attribute Selectors While not technically an HTML tip, attributes can also be used as selectors in CSS. You put square brackets around the attribute name and you’ll select all elements that contain that attribute. <style> [title] { background-color: red; } </style> <h1>List of <del>Suspects</del><ins>Co-workers</ins></h1> <ol> <li>Fred</li> <li>Rhonda</li> <li>Philomina</li> <li>Cranford</li> <li>Scott</li> <li title="the guilty one">Bob</li> <li>Bobbie</li> <li>Bobby</li> <li>"Rob"</li> </ol> See the Pen Attribute Selector [forked] by Undead Institute. There’s actually a whole lot more you can do with attribute selectors, but that’s the topic of another article — literally. Wrapping Up Okay, now that we’ve learned some trivia we can use to properly prosecute Bob’s office and yogurtorial transgressions, do you have a favorite HTML attribute I didn’t discuss? Show off your personal life-of-the-party energy in the comments. (And, yes, cool people have a favorite HTML attribute… really cool people… right? Right?? Right!?!?!?!?!)

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          How To Design For High-Traffic Events And Prevent Your Website From Crashing

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            Product drops and sales are a great way to increase revenue, but these events can result in traffic spikes that affect a site’s availability and performance. To prevent website crashes, you’ll have to make sure that the sites you design can handle large numbers of server requests at once. Let’s discuss how!

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            This article is a sponsored by Cloudways Product launches and sales typically attract large volumes of traffic. Too many concurrent server requests can lead to website crashes if you’re not equipped to deal with them. This can result in a loss of revenue and reputation damage. The good news is that you can maximize availability and prevent website crashes by designing websites specifically for these events. For example, you can switch to a scalable cloud-based web host, or compress/optimize images to save bandwidth. In this article, we’ll discuss six ways to design websites for high-traffic events like product drops and sales: Compress and optimize images, Choose a scalable web host, Use a CDN, Leverage caching, Stress test websites, Refine the backend. Let’s jump right in! How To Design For High-Traffic Events Let’s take a look at six ways to design websites for high-traffic events, without worrying about website crashes and other performance-related issues. 1. Compress And Optimize Images One of the simplest ways to design a website that accommodates large volumes of traffic is to optimize and compress images. Typically, images have very large file sizes, which means they take longer for browsers to parse and display. Additionally, they can be a huge drain on bandwidth and lead to slow loading times. You can free up space and reduce the load on your server by compressing and optimizing images. It’s a good idea to resize images to make them physically smaller. You can often do this using built-in apps on your operating system. There are also online optimization tools available like Tinify, as well as advanced image editing software like Photoshop or GIMP: Image format is also a key consideration. Many designers rely on JPG and PNG, but adaptive modern image formats like WebP can reduce the weight of the image and provide a better user experience (UX). You may even consider installing an image optimization plugin or an image CDN to compress and scale images automatically. Additionally, you can implement lazy loading, which prioritizes the loading of images above the fold and delays those that aren’t immediately visible. 2. Choose A Scalable Web Host The most convenient way to design a high-traffic website without worrying about website crashes is to upgrade your web hosting solution. Traditionally, when you sign up for a web hosting plan, you’re allocated a pre-defined number of resources. This can negatively impact your website performance, particularly if you use a shared hosting service. Upgrading your web host ensures that you have adequate resources to serve visitors flocking to your site during high-traffic events. If you’re not prepared for this eventuality, your website may crash, or your host may automatically upgrade you to a higher-priced plan. Therefore, the best solution is to switch to a scalable web host like Cloudways Autonomous: This is a fully managed WordPress hosting service that automatically adjusts your web resources based on demand. This means that you’re able to handle sudden traffic surges without the hassle of resource monitoring and without compromising on speed. With Cloudways Autonomous your website is hosted on multiple servers instead of just one. It uses Kubernetes with advanced load balancing to distribute traffic among these servers. Kubernetes is capable of spinning up additional pods (think of pods as servers) based on demand, so there’s no chance of overwhelming a single server with too many requests. High-traffic events like sales can also make your site a prime target for hackers. This is because, in high-stress situations, many sites enter a state of greater vulnerability and instability. But with Cloudways Autonomous, you’ll benefit from DDoS mitigation and a web application firewall to improve website security. 3. Use A CDN As you’d expect, large volumes of traffic can significantly impact the security and stability of your site’s network. This can result in website crashes unless you take the proper precautions when designing sites for these events. A content delivery network (CDN) is an excellent solution to the problem. You’ll get access to a collection of strategically-located servers, scattered all over the world. This means that you can reduce latency and speed up your content delivery times, regardless of where your customers are based. When a user makes a request for a website, they’ll receive content from a server that’s physically closest to their location. Plus, having extra servers to distribute traffic can prevent a single server from crashing under high-pressure conditions. Cloudflare is one of the most robust CDNs available, and luckily, you’ll get access to it when you use Cloudways Autonomous. You can also find optimization plugins or caching solutions that give you access to a CDN. Some tools like Jetpack include a dedicated image CDN, which is built to accommodate and auto-optimize visual assets. 4. Leverage Caching When a user requests a website, it can take a long time to load all the HTML, CSS, and JavaScript contained within it. Caching can help your website combat this issue. A cache functions as a temporary storage location that keeps copies of your web pages on hand (once they’ve been requested). This means that every subsequent request will be served from the cache, enabling users to access content much faster. The cache mainly deals with static content like HTML which is much quicker to parse compared to dynamic content like JavaScript. However, you can find caching technologies that accommodate both types of content. There are different caching mechanisms to consider when designing for high-traffic events. For example, edge caching is generally used to cache static assets like images, videos, or web pages. Meanwhile, database caching enables you to optimize server requests. If you’re expecting fewer simultaneous sessions (which isn’t likely in this scenario), server-side caching can be a good option. You could even implement browser caching, which affects static assets based on your HTTP headers. There are plenty of caching plugins available if you want to add this functionality to your site, but some web hosts provide built-in solutions. For example, Cloudways Autonomous uses Cloudflare’s edge cache and integrated object cache. 5. Stress Test Websites One of the best ways to design websites while preparing for peak traffic is to carry out comprehensive stress tests. This enables you to find out how your website performs in various conditions. For instance, you can simulate high-traffic events and discover the upper limits of your server’s capabilities. This helps you avoid resource drainage and prevent website crashes. You might have experience with speed testing tools like Pingdom, which assess your website performance. But these tools don’t help you understand how performance may be impacted by high volumes of traffic. Therefore, you’ll need to use a dedicated stress test tool like Loader.io: This is completely free to use, but you’ll need to register for an account and verify your website domain. You can then download your preferred file and upload it to your server via FTP. After that, you’ll find three different tests to carry out. Once your test is complete, you can take a look at the average response time and maximum response time, and see how this is affected by a higher number of clients. 6. Refine The Backend The final way to design websites for high-traffic events is to refine the WordPress back end. The admin panel is where you install plugins, activate themes, and add content. The more of these features that you have on your site, the slower your pages will load. Therefore, it’s a good idea to delete any old pages, posts, and images that are no longer needed. If you have access to your database, you can even go in and remove any archived materials. On top of this, it’s best to remove plugins that aren’t essential for your website to function. Again, with database access, you can get in there and delete any tables that sometimes get left behind when you uninstall plugins via the WordPress dashboard. When it comes to themes, you’ll want to opt for a simple layout with a minimalist design. Themes that come with lots of built-in widgets or rely on third-party plugins will likely add bloat to your loading times. Essentially, the lighter your back end, the quicker it will load. Conclusion Product drops and sales are a great way to increase revenue, but these events can result in traffic spikes that affect a site’s availability and performance. To prevent website crashes, you’ll have to make sure that the sites you design can handle large numbers of server requests at once. The easiest way to support fluctuating traffic volumes is to upgrade to a scalable web hosting service like Cloudways Autonomous. This way, you can adjust your server resources automatically, based on demand. Plus, you’ll get access to a CDN, caching, and an SSL certificate. Get started today!

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            What Does AI Really Mean?

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              We, as human beings, don’t worry too much about making sure the connections land at the right point. Our brain just works that way, declaratively. However, for building AI, we need to be more explicit. Let’s dive in!

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              In 2024, Artificial Intelligence (AI) hit the limelight with major advancements. The problem with reaching common knowledge and so much public attention so quickly is that the term becomes ambiguous. While we all have an approximation of what it means to “use AI” in something, it’s not widely understood what infrastructure having AI in your project, product, or feature entails. So, let’s break down the concepts that make AI tick. How is data stored and correlated, and how are the relationships built in order for an algorithm to learn how to interpret that data? As with most data-oriented architectures, it all starts with a database. Data As Coordinates Creating intelligence, whether artificial or natural, works in a very similar way. We store chunks of information, and we then connect them. Multiple visualization tools and metaphors show this in a 3-dimensional space with dots connected by lines on a graph. Those connections and their intersection are what make up for intelligence. For example, we put together “chocolate is sweet and nice” and “drinking hot milk makes you warm”, and we make “hot chocolate”. We, as human beings, don’t worry too much about making sure the connections land at the right point. Our brain just works that way, declaratively. However, for building AI, we need to be more explicit. So think of it as a map. In order for a plane to leave CountryA and arrive at CountryB it requires a precise system: we have coordinates, we have 2 axis in our maps, and they can be represented as a vector: [28.3772, 81.5707]. For our intelligence, we need a more complex system; 2 dimensions will not suffice; we need thousands. That’s what vector databases are. Our intelligence can now correlate terms based on the distance and/or angle between them, create cross-references, and establish patterns in which every term occurs. A specialized database that stores and manages data as high-dimensional vectors. It enables efficient similarity searches and semantic matching. Querying Per Approximation As stated in the last session, matching the search terms (your prompt) to the data is the exercise of semantic matching (it establishes the pattern in which keywords in your prompt are used within its own data), and the similarity search, the distance (angular or linear) between each entry. That’s actually a roughly accurate representation. What a similarity search does is define each of the numbers in a vector (that’s thousands of coordinates long), a point in this weird multi-dimensional space. Finally, to establish similarity between each of these points, the distance and/or angles between them are measured. This is one of the reasons why AI isn’t deterministic — we also aren’t — for the same prompt, the search may produce different outputs based on how the scores are defined at that moment. If you’re building an AI system, there are algorithms you can use to establish how your data will be evaluated. This can produce more precise and accurate results depending on the type of data. The main algorithms used are 3, and Each one of them performs better for a certain kind of data, so understanding the shape of the data and how each of these concepts will correlate is important to choosing the correct one. In a very hand-wavy way, here’s the rule-of-thumb to offer you a clue for each: Cosine Similarity Measures angle between vectors. So if the magnitude (the actual number) is less important. It’s great for text/semantic similarity Dot Product Captures linear correlation and alignment. It’s great for establishing relationships between multiple points/features. Euclidean Distance Calculates straight-line distance. It’s good for dense numerical spaces since it highlights the spatial distance. INFO When working with non-structured data (like text entries: your tweets, a book, multiple recipes, your product’s documentation), cosine similarity is the way to go. Now that we understand how the data bulk is stored and the relationships are built, we can start talking about how the intelligence works — let the training begin! Language Models A language model is a system trained to understand, predict, and finally generate human-like text by learning statistical patterns and relationships between words and phrases in large text datasets. For such a system, language is represented as probabilistic sequences. In that way, a language model is immediately capable of efficient completion (hence the quote stating that 90% of the code in Google is written by AI — auto-completion), translation, and conversation. Those tasks are the low-hanging fruits of AI because they depend on estimating the likelihood of word combinations and improve by reaffirming and adjusting the patterns based on usage feedback (rebalancing the similarity scores). As of now, we understand what a language model is, and we can start classifying them as large and small. Large Language Models (LLMs) As the name says, use large-scale datasets &mdash with billions of parameters, like up to 70 billion. This allows them to be diverse and capable of creating human-like text across different knowledge domains. Think of them as big generalists. This makes them not only versatile but extremely powerful. And as a consequence, training them demands a lot of computational work. Small Language Models (SLMs) With a smaller dataset, with numbers ranging from 100 million to 3 billion parameters. They take significantly less computational effort, which makes them less versatile and better suited for specific tasks with more defined constraints. SLMs can also be deployed more efficiently and have a faster inference when processing user input. Fine-Tunning Fine-tuning an LLM consists of adjusting the model’s weights through additional specialized training on a specific (high-quality) dataset. Basically, adapting a pre-trained model to perform better in a particular domain or task. As training iterates through the heuristics within the model, it enables a more nuanced understanding. This leads to more accurate and context-specific outputs without creating a custom language model for each task. On each training iteration, developers will tune the learning rate, weights, and batch-size while providing a dataset tailored for that particular knowledge area. Of course, each iteration depends also on appropriately benchmarking the output performance of the model. As mentioned above, fine-tuning is particularly useful for applying a determined task with a niche knowledge area, for example, creating summaries of nutritional scientific articles, correlating symptoms with a subset of possible conditions, etc. Fine-tuning is not something that can be done frequently or fast, requiring numerous iterations, and it isn’t intended for factual information, especially if dependent on current events or streamed information. Enhancing Context With Information Most conversations we have are directly dependent on context; with AI, it isn’t so much different. While there are definitely use cases that don’t entirely depend on current events (translations, summarization, data analysis, etc.), many others do. However, it isn’t quite feasible yet to have LLMs (or even SLMs) being trained on a daily basis. For this, a new technique can help: Retrieve-Augmented Generation (RAG). It consists of injecting a smaller dataset into the LLMs in order to provide it with more specific (and/or current) information. With a RAG, the LLM isn’t better trained; it still has all the generalistic training it had before — but now, before it generates the output, it receives an ingest of new information to be used. INFO RAG enhances the LLM’s context, providing it with a more comprehensive understanding of the topic. For an RAG to work well, data must be prepared/formatted in a way that the LLM can properly digest it. Setting it up is a multi-step process: Retrieval Query external data (such as web pages, knowledge bases, and databases). Pre-Processing Information undergoes pre-processing, including tokenization, stemming, and removal of stop words. Grounded Generation The pre-processed retrieved information is then seamlessly incorporated into the pre-trained LLM. RAG first retrieves relevant information from a database using a query generated by the LLM. Integrating an RAG to an LLM enhances its context, providing it with a more comprehensive understanding of the topic. This augmented context enables the LLM to generate more precise, informative, and engaging responses. Since it provides access to fresh information via easy-to-update database records, this approach is mostly for data-driven responses. Because this data is context-focused, it also provides more accuracy to facts. Think of a RAG as a tool to turn your LLM from a generalist into a specialist. Enhancing an LLM context through RAG is particularly useful for chatbots, assistants, agents, or other usages where the output quality is directly connected to domain knowledge. But, while RAG is the strategy to collect and “inject” data into the language model’s context, this data requires input, and that is why it also requires meaning embedded. Embedding To make data digestible by the LLM, we need to capture each entry’s semantic meaning so the language model can form the patterns and establish the relationships. This process is called embedding, and it works by creating a static vector representation of the data. Different language models have different levels of precision embedding. For example, you can have embeddings from 384 dimensions all the way to 3072. In other words, in comparison to our cartesian coordinates in a map (e.g., [28.3772, 81.5707]) with only two dimensions, an embedded entry for an LLM has from 384 to 3072 dimensions. Let’s Build I hope this helped you better understand what those terms mean and the processes which encompass the term “AI”. This merely scratches the surface of complexity, though. We still need to talk about AI Agents and how all these approaches intertwine to create richer experiences. Perhaps we can do that in a later article — let me know in the comments if you’d like that! Meanwhile, let me know your thoughts and what you build with this! Further Reading on SmashingMag “Using AI For Neurodiversity And Building Inclusive Tools,” Pratik Joglekar “How To Design Effective Conversational AI Experiences: A Comprehensive Guide,” Yinjian Huang “When Words Cannot Describe: Designing For AI Beyond Conversational Interfaces,” Maximillian Piras “AI’s Transformative Impact On Web Design: Supercharging Productivity Across The Industry,” Paul Boag

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              New Front-End Features For Designers In 2025

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                Searching for the most flexible front-end workflows and toolkits, it’s easy to forget how powerful some of the fundamentals on the web have become these days. This post is a journey through new front-end features and what they are capable of.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                Component-specific styling, styling parents based on their children, relative colors — the web platform is going through exciting times, and many things that required JavaScript in the past can today be achieved with one simple line of HTML and CSS. As we are moving towards 2025, it’s a good time to revisit some of the incredible new technologies that are broadly available and supported in modern browsers today. Let’s dive right in and explore how they can simplify your day-to-day work and help you build modern UI components. Table of Contents Below you’ll find quick jumps to topics you may be interested in, or skip the table of contents. anchor-positioning auto field-sizing container queries <dialog> exclusive accordions :focus-visible :has hidden=until-found high-definition colors <hr> in select inputmode min(), max(), clamp() relative colors responsive videos scroll behavior scroll snap text-wrap: balance :user-valid and :user-invalid View Transitions API CSS Container Queries And Style Queries Component-specific styling? What has long sounded like a dream to any developer, is slowly but surely becoming reality. Thanks to container queries, we can now query the width and style of the container in which components live. As Una Kravets points out in her introduction to style queries, this currently only works with CSS custom property values, but there are already some real-world use cases where style queries shine: They come in particularly handy when you have a reusable component with multiple variations or when you don’t have control over all of your styles but need to apply changes in certain cases. If you want to dive deeper into what’s possible with container style queries and the things we can — maybe — look forward to in the future, also be sure to take a look at Geoff Graham’s post. He dug deep into the more nuanced aspects of style queries and summarized the things that stood out to him. No More Typographic Orphans And Widows We all know those headlines where the last word breaks onto a new line and stands there alone, breaking the visual and looking, well, odd. Of course, there’s the good ol’ <br> to break the text manually or a <span> to divide the content into different parts. But have you heard of text-wrap: balance already? By applying the text-wrap: balance property, the browser will automatically calculate the number of words and divide them equally between two lines — perfect for page titles, card titles, tooltips, modals, and FAQs, for example. Ahmad Shadeed wrote a helpful guide to text-wrap: balance in which he takes a detailed look at the property and how it can help you make your headlines look more consistent. When dealing with large blocks of text, such as paragraphs, you might want to look into text-wrap: pretty to prevent orphans on the last line. Auto Field-Sizing For Forms Finding just the right size for an input field usually involves a lot of guesswork — or JavaScript — to count characters and increase the field’s height or width as a user enters text. CSS field-sizing is here to change that. With field-sizing, we can auto-grow inputs and text areas, but also auto-shrink short select menus, so the form always fits content size perfectly. All we need to make it happen is one line of CSS. Adam Argyle summarized everything you need to know about field-sizing, exploring in detail how field-sizing affects different <form> elements. To prevent your input fields from becoming too small or too large, it is also a good idea to insert some additional styles that keep them in shape. Adam shares a code snippet that you can copy-and-paste right away. Making Hidden Content Searchable Accordions are a popular UI pattern, but they come with a caveat: The content inside the collapsed sections is impossible to search with find-in-page search. By using the hidden=until-found attribute and the beforematch event, we can solve the problem and even make the content accessible to search engines. As Joey Arhar explains in his guide to making collapsed content searchable, you can replace the styles that hide the section with the hidden=until-found attribute. If your page also has another state that needs to be kept in sync with whether or not your section is revealed, he recommends adding a beforematch event listener. It will be fired on the hidden=until-found element right before the element is revealed by the browser. Styling Groups Within Select Menus It’s a small upgrade for the <select> element, but a mighty one: We can now add <hr> into the list of select options, and they will appear as separators to help visually break up the options in the list. If you want to refine things further, also be sure to take a look at <optgroup>. The HTML element lets you group options within a <select> element by adding a subheading for each group. Simpler Snapping For Scrollable Containers Sometimes, you need a quick and easy way to make an element a scrollable container. CSS scroll snap makes it possible. The CSS feature enables us to create a well-controlled scrolling experience that lets users precisely swipe left and right and snap to a specific item in the container. No JavaScript required. Ahmad Shadeed wrote a practical guide that walks you step by step through the process of setting up a container with scroll snap. You can use it to create image galleries, avatar lists, or other components where you want a user to scroll and snap through the content, whether it’s horizontally or vertically. Anchor Positioning For Tooltips And Popovers Whether you use it for footnotes, tooltips, connector lines, visual cross-referencing, or dynamic labels in charts, the CSS Anchor Positioning API enables us to natively position elements relative to other elements, known as anchors. In her introduction to the CSS Anchor Positioning API, Una Kravets summarized in detail how anchor positioning works. She takes a closer look at the mechanism behind anchor positioning, how to tether to one and multiple anchors, and how to size and position an anchor-positioned element based on the size of its anchor. Browser support is still limited, so you might want to use the API with some precautions. Una’s guide includes what to watch out for. High-Definition Colors With OKLCH And OKLAB With high-definition colors with LCH, okLCH, LAB, and okLAB that give us access to 50% more colors, the times of RGB/HSL might be over soon. To get you familiar with the new color spaces, Vitaly wrote a quick overview of what you need to know. Both OKLCH and OKLAB are based on human perception and can specify any color the human eye can see. While OKLAB works best for rich gradients, OKLCH is a fantastic fit for color palettes in design systems. OKLCH/OKLAB colors are fully supported in Chrome, Edge, Safari, Firefox, and Opera. Figma doesn’t support them yet. Relative Colors In CSS Let’s say you have a background color and want to reduce its luminosity by 25%, or you want to use a complementary color without having to calculate it yourself. The relative color syntax (RCS) makes it possible to create a new color based on a given color. To derive and compute a new color, we can use the from keyword for color functions (color(), hsl(), oklch(), etc.) to modify the values of the input color. Adam Argyle shares some code snippets of what this looks like in practice, or check the spec for more details. Smooth Transitions With The View Transitions API There are a number of use cases where a smooth visual transition can make the user experience more engaging. When a thumbnail image on a product listing page transitions into a full-size image on the product detail page, for example, or when you have a fixed navigation bar that stays in place as you navigate from one page to another. The View Transitions API helps us create seamless visual transitions between different views on a site. View transitions can be triggered not only on a single document but also between two different documents. Both rely on the same principle: The browser takes snapshots of the old and new states, the DOM gets updated while rendering is suppressed, and the transitions are powered by CSS Animations. The only difference lies in how you trigger them, as Bramus Van Damme explains in his guide to the View Transitions API. A good alternative to single page apps that often rely on heavy JavaScript frameworks. Exclusive Accordions The ‘exclusive accordion’ is a variation of the accordion component. It only allows one disclosure widget to be open at the same time, so when a user opens a new one, the one that is already open will be closed automatically to save space. Thanks to CSS, we can now create the effect without a single line of JavaScript. To build an exclusive accordion, we need to add a name attribute to the <details> elements. When this attribute is used, all <details> elements that have the same name value form a semantic group and behave as an exclusive accordion. Bramus Van Damme summarized in detail how it works. Live And Late Validation When we use :valid and :invalid to apply styling based on a user’s input, there’s a downside: a form control that is required and empty will match :invalid even if a user hasn’t started interacting with it yet. To prevent this from happening, we usually had to write stateful code that keeps track of input a user has changed. But not anymore. With :user-valid and :user-invalid, we now have a native CSS solution that handles all of this automatically. Contrary to :valid and :invalid, the :user-valid and :user-invalid pseudo-classes give users feedback about mistakes only after they have changed the input. :user-valid and :user-invalid work with input, select, and textarea controls. Smooth Scrolling Behavior Imagine you have a scrolling box and a series of links that target an anchored position inside the box. When a user clicks on one of the links, it will take them to the content section inside the scrolling box — with a rather abrupt jump. The scroll-behavior property makes the scrolling transition a lot smoother, only with CSS. When setting the scroll-behavior value to smooth, the scrolling box will scroll in a smooth fashion using a user-agent-defined easing function over a user-agent-defined period of time. Of course, you can also use scroll-behavior: auto, and the scrolling box will scroll instantly. Making Focus Visible Focus styles are essential to help keyboard users navigate a page. However, for mouse users, it can be irritating when a focus ring appears around a button or link as they click on it. :focus-visible is here to help us create the best experience for both user groups: It displays focus styles for keyboard users and hides them for mouse users. :focus-visible applies while an element matches the :focus pseudo-class and the User Agent determines via heuristics that the focus should be made visible on the element. Curious how it works in practice? MDN Web Docs highlights the differences between :focus and :focus-visible, what you need to consider accessibility-wise, and how to provide a fallback for old browser versions that don’t support :focus-visible. Styling Parents Based On Children Historically, CSS selectors have worked in a top-down fashion, allowing us to style a child based on its parent. The new CSS pseudo-class :has works the other way round: We can now style a parent based on its children. But that’s not all yet. Josh W. Comeau wrote a fantastic introduction to :has in which he explores real-world use cases that show what the pseudo-class is capable of. :has is not limited to parent-child relationships or direct siblings. Instead, it lets us style one element based on the properties or status of any other element in a totally different container. And it can be used as a sort of global event listener, as Josh shows — to disable scrolling on a page when a modal is open or to create a JavaScript-free dark mode toggle, for example. Interpolate Between Values For Type And Spacing CSS comparison functions min(), max(), and clamp() are today supported in all major browsers, providing us with an effective way to create dynamic layouts with fluid type scales, grids, and spacing systems. To get you fit for using the functions in your projects right away, Ahmad Shadeed wrote a comprehensive guide in which he explains everything you need to know about min(), max(), and clamp(), with practical examples and use cases and including all the points of confusion you might encounter. If you’re looking for a quick and easy way to create fluid scales, the Fluid Type Scale Calculator by Utopia has got your back. All you need to do is define min and max viewport widths and the number of scale steps, and the calculator provides you with a responsive preview of the scale and the CSS code snippet. Reliable Dialog And Popover If you’re looking for a quick way to create a modal or popup, the <dialog> HTML element finally offers a native (and accessible!) solution to help you get the job done. It represents a modal or non-modal dialog box or other interactive component, such as a confirmation prompt or a subwindow used to enter data. While modal dialog boxes interrupt interaction with a page, non-modal dialog boxes allow interaction with the page while the dialog is open. Adam Argyle published some code snippets that show how <dialog> can block pop-ups and popovers for non-blocking menus, out of the box. Responsive HTML Video And Audio In 2014, media attribute support for HTML video sources was deleted from the HTML standard. Last year, it made a comeback, which means that we can use media queries for delivering responsive HTML videos. Scott Jehl summarized how responsive HTML video — and even audio — works, what you need to consider when writing the markup, and what other types of media queries can be used in combination with HTML video. The Right Virtual Keyboard On Mobile It’s a small detail, but one that adds to a well-considered user experience: displaying the most comfortable touchscreen keyboard to help a user enter their information without having to switch back and forth to insert numbers, punctuation, or special characters like an @ symbol. To show the right keyboard layout, we can use inputmode. It instructs the browser which keyboard to display and supports values for numeric, telephone, decimal, email, URL, and search keyboards. To further improve the UX, we can add the enterkeyhint attribute: it adjusts the text on the Enter key. If no enterkeyhint is used, the user agent might use contextual information from the inputmode attribute. A Look Into The Future As we are starting to adopt all of these shiny new front-end features in our projects, the web platform is, of course, constantly evolving — and there are some exciting things on the horizon already! For example, we are very close to getting masonry layout, fully customizable drop-downs with <selectmenu>, and text-box trimming for adjusting fonts to be perfectly aligned within the grid. Kudos to all the wonderful people who are working tirelessly to push the web forward! 👏 In the meantime, we hope you found something helpful in this post that you can apply to your product or application right away. Happy tinkering! Smashing Weekly Newsletter You want to stay on top of what’s happening in the world of front-end and UX? With our weekly newsletter, we aim to bring you useful, practical tidbits and share some of the helpful things that folks are working on in the web industry. Every issue is curated, written, and edited with love and care. No third-party mailings or hidden advertising. Also, when you subscribe, you really help us pay the bills. Thank you for your kind support!

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                New Year, New Hopes, New Dreams (January 2025 Wallpapers Edition)

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  Maybe 2025 has already started as you’re reading this, maybe you’re still waiting for the big countdown to begin — either way, it’s never too late or too early for some New Year’s inspiration! Our new collection of desktop wallpapers has got you covered.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  The new year is the perfect occasion to tidy up your desktops and start on a fresh, clean slate. No clutter, just the things you really need and plenty of space for what’s about to come. So how about some new desktop wallpapers to make the makeover complete and spark your inspiration this January? More than thirteen years ago, we started our monthly wallpapers series to bring you a new collection of beautiful and unique desktop wallpapers every month. And, of course, this month is no exception. In this post, you’ll find January wallpapers to inspire, make you smile, or just to cater for some happy pops of color on a dark winter day. All of them are created with love by artists and designers from across the globe and can be downloaded for free. A big thank you to everyone who shared their designs with us — you are truly smashing! Have a happy and healthy 2025, everyone! You can click on every image to see a larger preview. We respect and carefully consider the ideas and motivation behind each and every artist’s work. This is why we give all artists the full freedom to explore their creativity and express emotions and experience through their works. This is also why the themes of the wallpapers weren’t anyhow influenced by us but rather designed from scratch by the artists themselves. Submit your wallpaper design! 👩‍🎨 Feeling inspired? We are always looking for creative talent and would love to feature your desktop wallpaper in one of our upcoming posts. We can’t wait to see what you’ll come up with! Celebrate Squirrel Appreciation Day! “Join us in honoring our furry little forest friends this Squirrel Appreciation Day! Whether they’re gathering nuts, building cozy homes, or brightening up winter days with their playful antics, squirrels remind us to treasure nature’s small wonders. Let’s show them some love today!” — Designed by PopArt Studio from Serbia. preview with calendar: 320x480, 640x480, 800x480, 800x600, 1024x768, 1024x1024, 1152x864, 1280x720, 1280x800, 1280x960, 1280x1024, 1400x1050, 1440x900, 1600x1200, 1680x1050, 1680x1200, 1920x1080, 1920x1200, 1920x1440, 2560x1440 without calendar: 320x480, 640x480, 800x480, 800x600, 1024x768, 1024x1024, 1152x864, 1280x720, 1280x800, 1280x960, 1280x1024, 1400x1050, 1440x900, 1600x1200, 1680x1050, 1680x1200, 1920x1080, 1920x1200, 1920x1440, 2560x1440 Happy New Year ’86 Designed by Ricardo Gimenes from Spain. preview with calendar: 640x480, 800x480, 800x600, 1024x768, 1024x1024, 1152x864, 1280x720, 1280x800, 1280x960, 1280x1024, 1366x768, 1400x1050, 1440x900, 1600x1200, 1680x1050, 1680x1200, 1920x1080, 1920x1200, 1920x1440, 2560x1440, 3840x2160 without calendar: 640x480, 800x480, 800x600, 1024x768, 1024x1024, 1152x864, 1280x720, 1280x800, 1280x960, 1280x1024, 1366x768, 1400x1050, 1440x900, 1600x1200, 1680x1050, 1680x1200, 1920x1080, 1920x1200, 1920x1440, 2560x1440, 3840x2160 Who Wants To Be King Designed by Ricardo Gimenes from Spain. preview with calendar: 640x480, 800x480, 800x600, 1024x768, 1024x1024, 1152x864, 1280x720, 1280x800, 1280x960, 1280x1024, 1366x768, 1400x1050, 1440x900, 1600x1200, 1680x1050, 1680x1200, 1920x1080, 1920x1200, 1920x1440, 2560x1440, 3840x2160 without calendar: 640x480, 800x480, 800x600, 1024x768, 1024x1024, 1152x864, 1280x720, 1280x800, 1280x960, 1280x1024, 1366x768, 1400x1050, 1440x900, 1600x1200, 1680x1050, 1680x1200, 1920x1080, 1920x1200, 1920x1440, 2560x1440, 3840x2160 Bird Bird Bird Bird “Just four birds, ready for winter.” — Designed by Vlad Gerasimov from Georgia. preview without calendar: 800x480, 800x600, 1024x600, 1024x768, 1152x864, 1280x720, 1280x800, 1280x960, 1280x1024, 1366x768, 1400x1050, 1440x900, 1440x960, 1600x900, 1600x1200, 1680x1050, 1680x1200, 1920x1080, 1920x1200, 1920x1440, 2560x1440, 2560x1600, 2880x1800, 3072x1920, 3840x2160, 5120x2880 Cheerful Chimes City Designed by Design Studio from India. preview without calendar: 1440x900, 1600x1200, 1680x1050, 1680x1200, 1920x1080, 1920x1200, 1920x1440, 2560x1440 A Fresh Start Designed by Ricardo Gimenes from Spain. preview without calendar: 640x480, 800x480, 800x600, 1024x768, 1024x1024, 1152x864, 1280x720, 1280x800, 1280x960, 1280x1024, 1366x768, 1400x1050, 1440x900, 1600x1200, 1680x1050, 1680x1200, 1920x1080, 1920x1200, 1920x1440, 2560x1440, 3840x2160 Cold… Penguins! “The new year is here! We waited for it like penguins. We look at the snow and enjoy it! — Designed by Veronica Valenzuela from Spain. preview without calendar: 640x480, 800x480, 1024x768, 1280x720, 1280x800, 1440x900, 1600x1200, 1920x1080, 1920x1440, 2560x1440 Open The Doors Of The New Year “January is the first month of the year and usually the coldest winter month in the Northern hemisphere. The name of the month of January comes from ‘ianua’, the Latin word for door, so this month denotes the door to the new year and a new beginning. Let’s open the doors of the new year together and hope it will be the best so far!” — Designed by PopArt Studio from Serbia. preview without calendar: 320x480, 640x480, 800x480, 800x600, 1024x768, 1024x1024, 1152x864, 1280x720, 1280x800, 1280x960, 1280x1024, 1366x768, 1400x1050, 1440x900, 1600x1200, 1680x1050, 1680x1200, 1920x1080, 1920x1200, 1920x1440, 2560x1440 Boom! Designed by Elise Vanoorbeek from Belgium. preview without calendar: 1024x768, 1152x864, 1280x720, 1280x800, 1280x960, 1280x1024, 1366x768, 1400x1050, 1440x900, 1600x1200, 1680x1050, 1680x1200, 1920x1080, 1920x1200, 1920x1440, 2560x1440 Winter Leaves Designed by Nathalie Ouederni from France. preview without calendar: 320x480, 1024x768, 1280x1024, 1440x900, 1600x1200, 1680x1200, 1920x1200, 2560x1440 Start Somewhere “If we wait until we’re ready, we’ll be waiting for the rest of our lives. Start today — somewhere, anywhere.” — Designed by Shawna Armstrong from the United States. preview without calendar: 1280x720, 1280x800, 1280x960, 1280x1024, 1400x1050, 1440x900, 1600x1200, 1680x1050, 1920x1080, 1920x1200, 1920x1440, 2560x1440 Peaceful Mountains “When all the festivities are over, all we want is some peace and rest. That’s why I made this simple flat art wallpaper with peaceful colors.” — Designed by Jens Gilis from Belgium. preview without calendar: 640x480, 800x600, 1024x768, 1152x864, 1280x720, 1280x800, 1280x960, 1366x768, 1400x1050, 1440x900, 1600x1200, 1680x1050, 1920x1080, 1920x1200, 1920x1440, 2560x1440 Be Awesome Today “A little daily motivation to keep your cool during the month of January.” — Designed by Amalia Van Bloom from the United States. preview without calendar: 640x960, 1024x768, 1280x800, 1280x1024, 1440x900, 1920x1200, 2560x1440 Yogabear Designed by Ricardo Gimenes from Spain. preview without calendar: 640x480, 800x480, 800x600, 1024x768, 1024x1024, 1152x864, 1280x720, 1280x800, 1280x960, 1280x1024, 1366x768, 1400x1050, 1440x900, 1600x1200, 1680x1050, 1680x1200, 1920x1080, 1920x1200, 1920x1440, 2560x1440, 3840x2160 Winter Getaway “What could be better, than a change of scene for a week? Even if you are too busy, just think about it.” — Designed by Igor Izhik from Canada. preview without calendar: 1024x768, 1280x720, 1280x800, 1280x960, 1280x1024, 1400x1050, 1440x900, 1600x1200, 1680x1050, 1680x1200, 1920x1080, 1920x1200, 1920x1440, 2560x1440, 2560x1600 Don Quijote, Here We Go! “This year we are going to travel through books, and you couldn’t start with a better one than Don Quijote de la Mancha!” — Designed by Veronica Valenzuela Jimenez from Spain. preview without calendar: 640x480, 800x480, 1024x768, 1280x720, 1280x800, 1440x900, 1600x1200, 1920x1080, 1920x1440, 2560x1440 The Little Paradox Designed by Ricardo Gimenes from Spain. preview without calendar: 640x480, 800x480, 800x600, 1024x768, 1024x1024, 1152x864, 1280x720, 1280x800, 1280x960, 1280x1024, 1366x768, 1400x1050, 1440x900, 1600x1200, 1680x1050, 1680x1200, 1920x1080, 1920x1200, 1920x1440, 2560x1440, 3840x2160 A New Beginning “I wanted to do a lettering-based wallpaper because I love lettering. I chose January because for a lot of people the new year is perceived as a new beginning and I wish to make them feel as positive about it as possible! The idea is to make them feel like the new year is (just) the start of something really great.” — Designed by Carolina Sequeira from Portugal. preview without calendar: 320x480, 1280x1024, 1680x1050, 2560x1440 Happy Hot Tea Month “You wake me up to a beautiful day; lift my spirit when I’m feeling blue. When I’m home you relieve me of the long day’s stress. You help me have a good time with my loved ones; give me company when I’m all alone. You’re none other than my favourite cup of hot tea.” — Designed by Acodez IT Solutions from India. preview without calendar: 320x480, 640x480, 800x480, 800x600, 1024x768, 1024x1024, 1152x864, 1280x720, 1280x960, 1280x1024, 1366x768, 1400x1050, 1440x900, 1600x1200, 1680x1050, 1680x1200, 1920x1080, 1920x1200, 1920x1440, 2560x1440 Don’t Forget Your Vitamins “Discover the seasonal fruits and vegetables. In January: apple and banana enjoying the snow!” — Designed by Vitaminas Design from Spain. preview without calendar: 320x480, 1280x800, 1280x1024, 1440x900, 1920x1080, 2560x1440 Dare To Be You “The new year brings new opportunities for each of us to become our true selves. I think that no matter what you are — like this little monster — you should dare to be the true you without caring what others may think. Happy New Year!” — Designed by Maria Keller from Mexico. preview without calendar: 320x480, 640x480, 640x1136, 750x1334, 800x480, 800x600, 1024x768, 1024x1024, 1152x864, 1242x2208, 1280x720, 1280x800, 1280x960, 1280x1024, 1366x768, 1400x1050, 1440x900, 1600x1200, 1680x1050, 1680x1200, 1920x1080, 1920x1440, 2560x1440, 2880x1800 Angel In Snow Designed by Brainer from Ukraine. preview without calendar: 800x600, 1024x768, 1152x864, 1280x800, 1280x960, 1400x1050, 1440x900, 1600x1200, 1680x1050, 1680x1260, 1920x1200, 1920x1440 Snowman Designed by Ricardo Gimenes from Spain. preview without calendar: 320x480, 640x480, 800x480, 800x600, 1024x768, 1024x1024, 1152x864, 1280x720, 1280x800, 1280x960, 1280x1024, 1366x768, 1400x1050, 1440x900, 1600x1200, 1680x1050, 1680x1200, 1920x1080, 1920x1200, 1920x1440, 2560x1440 Oaken January “In our country, Christmas is celebrated in January when oak branches and leaves are burnt to symbolize the beginning of the new year and new life. It’s the time when we gather with our families and celebrate the arrival of the new year in a warm and cuddly atmosphere.” — Designed by PopArt Studio from Serbia. preview without calendar: 320x480, 640x480, 800x480, 800x600, 1024x768, 1024x1024, 1152x864, 1280x720, 1280x800, 1280x960, 1280x1024, 1366x768, 1400x1050, 1440x900, 1600x1200, 1680x1050, 1680x1200, 1920x1080, 1920x1200, 1920x1440, 2560x1440 Rubber Ducky Day “Winter can be such a gloomy time of the year. The sun sets earlier, the wind feels colder, and our heating bills skyrocket. I hope to brighten up your month with my wallpaper for Rubber Ducky Day!” — Designed by Ilya Plyusnin from Belgium. preview without calendar: 320x480, 640x480, 800x480, 800x600, 1024x768, 1024x1024, 1152x864, 1280x720, 1280x800, 1280x960, 1280x1024, 1366x768, 1400x1050, 1440x900, 1600x1200, 1680x1050, 1680x1200, 1920x1080, 1920x1200, 1920x1440, 2560x1440 The Early January Bird “January is the month of a new beginning, hope, and inspiration. That’s why it reminds me of an early bird.” — Designed by Zlatina Petrova from Bulgaria. preview without calendar: 320x480, 640x480, 800x480, 800x600, 1024x768, 1024x1024, 1152x864, 1280x720, 1280x800, 1280x960, 1280x1024, 1400x1050, 1440x900, 1600x1200, 1680x1050, 1680x1200, 1920x1080, 1920x1200, 1920x1440, 2560x1440 A New Start “The new year brings hope, festivity, lots and lots of resolutions, and many more goals that need to be achieved.” — Designed by Damn Perfect from India. preview without calendar: 320x480, 640x480, 800x480, 800x600, 1024x768, 1024x1024, 1152x864, 1280x720, 1280x800, 1280x960, 1280x1024, 1366x768, 1400x1050, 1440x900, 1600x1200, 1680x1050, 1680x1200, 1920x1080, 1920x1200, 1920x1440, 2560x1440 Wolf Month “Wolf-month (in Dutch ‘wolfsmaand’) is another name for January.” — Designed by Chiara Faes from Belgium. preview without calendar: 640x480, 800x600, 1024x768, 1152x864, 1280x720, 1280x800, 1280x960, 1366x768, 1400x1050, 1440x900, 1600x1200, 1680x1050, 1920x1080, 1920x1200, 1920x1440, 2560x1440

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  The Design Leader Dilemma

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    Design leaders are expected to deliver the impossible. Instead of trying, we need to redefine our role from implementor to enabler.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    Many design leaders find themselves in an impossible situation. On one side, senior management have read articles trumpeting the incredible ROI of user experience design. McKinsey tells us that design-led companies achieve 56% higher returns to shareholders. Forrester reports that every dollar invested in UX brings 100 dollars in return. Yet the reality I encounter when talking to design leaders is very different. Most are desperately under-resourced, with tiny teams expected to support hundreds of projects across their organizations. The result? We’re spread so thin that we can barely scratch the surface of what needs doing. The problem isn’t just about resources. It’s about expectations and how we define our role. Too often, we position ourselves (or are positioned by others) as implementors — the people who do the user research, create the prototypes, and run the usability tests. But with the scale of digital touching every corner of our organizations, that’s simply not sustainable. Time For A New Approach We need to stop trying to do everything ourselves and instead focus on empowering others across the organization to improve the user experience. In other words, we need to become true leaders rather than just practitioners. This isn’t about giving up control or lowering standards. It’s about maximizing our impact by working through others. Think about it: would you rather be directly involved in 10% of projects or have some influence over 90% of them? What Does This Look Like In Practice? First, we need to shift our mindset from doing to enabling. This means: Offering targeted services rather than trying to be involved in everything; Providing coaching and mentoring to help others understand UX principles; Creating resources that empower others to make better UX decisions; Setting standards and guidelines that can scale across the organization. Let’s break down each of these areas. Targeted Services Instead of trying to be involved in every project, focus on providing specific, high-value services that can make the biggest impact. This might include: Running discovery phases for major initiatives By strategically initiating discovery phases for critical projects, you ensure that they start with a strong, user-focused foundation. This can involve tools like the Strategic User-Driven Project Assessment (SUPA), which helps validate ideas by assessing audience value, user needs, feasibility, and risks before committing to major investments. SUPA ensures projects are not just built right but are the right ones to build. Project-Specific UX Guidance Regular feedback on design assets throughout a project keeps UX principles front and center. This can be achieved by offering UX audits, periodic check-ins to assess progress, or design reviews at key milestones. Facilitating workshops and problem-solving sessions Leading targeted workshops or brainstorming sessions empowers teams to overcome design challenges on their own with your guidance. These tailored sessions help teams understand how to make better user-centered decisions and solve issues themselves, spreading UX capabilities beyond your team. The key is to be strategic about where you spend your time, focusing on activities that will have the greatest ripple effect across the organization. Coaching And Mentoring One of the most effective ways to scale your impact is through coaching. This could include: UX Office Hours Designate times where anyone in the organization can drop in to get quick UX advice. This informal setting can solve small issues before they snowball and helps stakeholders learn as they go. One-on-One or Group Coaching Scheduled check-ins with individuals or teams are great opportunities to address challenges directly, mentor those who need extra support, and ensure alignment with best practices. Regular 1:1 or group coaching keeps UX priorities on track and provides valuable guidance when and where it’s needed most. Tailored Problem-Solving Sessions Providing bespoke guidance for specific challenges that teams encounter empowers them to tackle design obstacles while internalizing the principles of good UX. These problem-solving sessions can be invaluable in ensuring teams can autonomously address future problems. The goal isn’t to turn everyone into UX experts but to help them understand enough to make better decisions in their daily work. It’s also important to recognize that others might not initially deliver work at the same level of quality that you would. This is okay. The primary goal is to get people engaged and excited about UX. If we criticize them every time they fall short of perfection, we risk undermining their enthusiasm. Instead, we need to foster a supportive environment where improvement happens over time. Creating Resources Develop tools and resources that help others apply UX principles independently. For example: Design Systems Create and maintain a comprehensive design system that integrates UX best practices into the UI across the organization. A well-crafted design system ensures that everyone, from developers to designers, aligns on consistent best practices, making it easier for teams to work independently while still maintaining high standards. This includes reusable code components, clear documentation, and alignment between design and development. UX Tool Suite Providing teams with pre-selected tools for user research, prototyping, and user testing helps maintain quality and saves time. With tools for everything from user research to usability testing, you provide the resources teams need to conduct UX activities on their own without extensive onboarding. Research Repository Maintain a centralized repository of user research findings that can be accessed by anyone across the organization. A well-organized research repository can reduce duplication of effort, provide insights across different initiatives, and allow teams to learn from each other’s findings. This promotes consistent application of user insights across projects. Supplier Lists Providing a vetted list of suppliers and external agencies helps ensure consistency when work is outsourced. It provides quick access to high-quality resources, mitigates risk, and builds trust with suppliers who understand your standards. Self-Service Training Resources Create a library of on-demand training materials that teams can access when needed. This should include video tutorials, interactive exercises, case studies, and step-by-step guides for common UX tasks like conducting user interviews, creating personas, or running usability tests. Unlike scheduled workshops, self-paced learning allows people to access knowledge exactly when they need it, leading to better retention and practical application. These resources should be practical and accessible, making it easy for teams to do the right thing. Setting Standards Create a framework that guides UX decisions across the organization: Design Principles Establish core design principles that align with your organization’s values and user-centered goals. These principles help ensure consistency and clarity in decision-making. For example, define around six to ten principles that stakeholders across the organization have voted on and agreed upon, ensuring broader buy-in and consistent decision-making. Policies for UX Develop clear policies that standardize processes like work requests, user research and testing, and stakeholder involvement. These policies help set expectations, keep efforts aligned with organizational goals, and make it easier for non-UX professionals to understand and comply with best practices. Project Prioritization Policies Having clear guidelines on how projects are prioritized ensures that UX gets the attention it needs in the planning stages, preventing it from being overlooked or marginalized. Establish policies that align project value to user needs and organizational priorities. The key is to make these standards helpful rather than bureaucratic — they should enable better work, not create unnecessary obstacles. Bringing It All Together All of these elements should come together in what I call a UX Playbook — a single source of truth that contains everything teams need to deliver better user experiences. This isn’t just another document to gather dust; it’s a living resource that demonstrates your value as a leader and helps others get started on their UX journey. The shift from practitioner to leader isn’t easy. It requires letting go of some control and trusting others to carry forward UX principles. But it’s the only way to create lasting change at scale. If you’re struggling with this transition, I am running a workshop on design leadership in February. I would love to discuss your situation there.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    Three Approaches To Amplify Your Design Projects

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      There are many ways to elevate a design project from good to incredible. For web and product designers, it’s not just about adding more animations and flair. What it truly comes down to is a reframing of your thought processes starting before the project even kicks off. Olivia De Alba presents three approaches that designers can implement and which will change the way they make their projects more successful.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      What makes an incredible project? Is it the client? The type of project? An exorbitant budget? While those things help to create the environment in which a great project can thrive, what truly makes a project something powerful is you. No, this isn’t some pep talk on why you are the ultimate weapon — but yes, you are if you want to be. I am simply a web and product designer writing down my observations in order to give others the tools to make their project experiences all the better for it. Still with me? Let me tell you about what I’ve discovered over the years working as an agency designer. There are three approaches that have completely changed the way my projects run from start to finish. I have found that since implementing all three, my work and my interactions with clients and coworkers have blossomed. Here they are: Unlearn previous experiences through Reframing. Tap into your background with Connection Paths. Take up your own space. Period. In this article, you will find explanations of each approach and connected practical examples — as well as real-life ones from my project work at Fueled + 10up — to show you how they can be applied to projects. With that said, let’s dive in. Approach 1: Unlearn Previous Experiences Through Reframing While some of the things that we have learned over the years spent in design are invaluable, amidst those previous experiences, there are also the ones that hold us back. Unlearning ingrained lessons is not an easy thing to do. Rather, I challenge you to reframe them and get into the habit of asking yourself, “Am I stopping short creatively because I have always gone this far?” or “Am I associating an implied response from others due to a previous experience and therefore not doing enough for the project?” Let me give you some examples of thoughts that may arise on a given project and how you can reframe them in a better way. Initial Thought “I’ve designed cards thousands of times. Therefore, there are only so many ways you can do it.” As you know, in 99.9% of website design projects, a card design is required. It may seem that every possible design ever imagined has been created up to this point — a fair reasoning, isn’t it? However, stifling yourself from the very get-go with this mentality will only serve to produce expected and too-well-known results. Reframed Thought Instead, you could approach this scenario with the following reframed thought: “I’ve designed cards thousands of times, so let me take what I’ve learned, do some more exploration, and iterate on what could push these cards further for this particular project.” With this new outlook, you may find yourself digging deeper to pull on creative threads, inevitably resulting in adaptive thinking. A good exercise to promote this is the Crazy 8’s design exercise. In this format, you can pull forth rapid ideas — some good, some not so good — and see what sticks. This method is meant to get your brain working through a simple solution by tackling it from multiple angles. Real-Life Example Here is a real-life example from one of my projects in which I had to explore cards on a deeper level. This client’s website was primarily made up of cards of varying content and complexity. In the initial stages of design, I worked to define how we could differentiate cards, with prominence in size, imagery, and color, as well as motion and hover effects. What I landed on was a flexible system that had three tiers and harmonized well together. Knowing they had content that they wanted to be highlighted in a distinctive way, I created a Featured Card and tied it to the brand identity with the cutout shape in the image masking. I also included the glass effect on top to allude to the brand’s science background and ensure the text was accessible. For the Stacked Card, I introduced a unique hover effect pattern: depending on where the card was in a given grid, it would determine the card’s hover color. Lastly, for the Horizontal Card, I wanted to create something that had equal emphasis on the image and content and that could also stand alone well, even without an image. While these cards include what most cards usually do, the approach I took and the visual language used was unique to the client. Instead of working on these too quickly, I ventured down a different path that took a little more thought, which led me to a result that felt in tune with the client’s needs. It also pushed me outside of what I knew to be the standard, straightforward approach. Initial Thought “Fast is better. Clients and project teams want me to be fast, so it’s okay if I cut down on exploration.” In most projects, speed is indeed rewarded. It keeps the project within its budget constraints, the project managers are happy, and ultimately, the clients are happy, too. However, what it can end up doing instead is generating errors in the process and hindering design exploration. Reframed Thought In this scenario, you can reframe this like so: “I like to work fast because I want the team to be successful. In addition, I want to make sure I have not only produced high-quality work but also explored whether this is the best and most creative solution for the project.” With this new outlook, you are still looking out for what clients and project teams want (successful outcomes), but you have also enriched the experience by fully executing your design expertise rather than just churning out work. One recommendation here is to always ensure you are communicating with your project team about the budget and timelines. Keeping yourself aware of these key goals will allow you to pace when to push for more exploration and when to dial it in. Real-Life Example I experienced this on a project of mine when a client’s piece of feedback seemed clear-cut, but as we entered a third round of design surrounding it, it revealed that it was much more complicated. The client, Cleveland Public Library, had approved a set of wireframes for their homepage that illustrated a very content-heavy hero, but when it came to the design phase, they were delighted by a simpler, more bold design for a block that I created in my preliminary design explorations. At first, I thought it was obvious: let’s just give them a dialed-in, simple hero design and be done with it. I knew the hours were precious on this project, and I wanted to save time for later on as we got into the finer design details of the pages. However, this was an error on my part. After taking a step back and removing speed as a key factor during this phase of the project, I found the solution they actually needed: a content-heavy hero showcasing the breadth of their offerings, melded with the boldness of the more pared-down design. And guess what? This variant was approved instantly! Now that I have shown you two examples of how to unlearn previous experiences, I hope you can see the value of reframing those moments in order to tap into a more uninhibited and unexplored creative path. Of course, you should expect that it will take several implementations to start feeling the shift towards inherent thinking — even I need to remind myself to pause and reframe, like in the last example. Rome wasn’t built in a day, as they say! Try This I challenge you to identify a few moments on a recent project where you could have paused, reflected, and used more creativity. What would you have done differently? Approach 2: Tap Into Your Background With Connection Paths I know I just talked about unlearning some of our previous experiences to unlock creativity, but what about the ones we may want to tap into to push us even further? Every designer has an array of passions, memories, and experiences that have culminated into what makes us who we are today. We often have a work self — professional and poised, and a personal self — exploding with hobbies. How can we take those unique facets of our personalities and apply them to our projects? Creating connections with projects and clients on a deeper level is a major way to make use of our personal experiences and knowledge. It can help to add inspiration where you otherwise may not have found that same spark on a project or subject matter. Let me walk you through what I like to call the Three Connection Paths. I’ll also show you how you can pull from these and apply them to your projects. Direct Path This connection path is one in which you have overlapping interests with the client or subject matter. An example of this is a client from the video game industry, and you play their video games. Seems like an obvious connection! You can bring in your knowledge and love for the game industry and their work. You could propose easter eggs and tie-ins to their games on their website. It’s a match made in heaven. Cross Path This connection path is one in which you cross at a singular point with the client or subject matter. An example of this is a client, which is a major restaurant chain, and you used to work in the food industry. With your background, you understand what it is like to work at a restaurant, so you might suggest what CTA’s or fun graphics would be important for a staff-centric site. Network Path This connection path is one in which you are tethered to the client or subject matter through who you know. An example of this is a client in the engineering field, and one of your family members is an engineer. You can then ask your family members for insights or what would be a good user experience for them on a redesigned website. Sometimes, you won’t be so lucky as to align with a client in one of the Three Connection Paths, but you can still find ways to add a layered experience through other means, such as your skillset and research. In the last example, say you know nothing about engineering nor have a connection to someone who does, but you are an excellent copy editor outside of work. You can propose tweaking the verbiage on their hero section to emphasize their goals all the more. This shows care and thoughtfulness, giving the client an experience they are sure to appreciate. Real-Life Example A real-life example in which I implemented a Direct Connection Path on a project was for Comics Kingdom’s website redesign. When I was younger, I wanted to be a manga creator, so this client being an intermediary between comic readers and creators resonated with me. Not only that, but I still practice illustration, so I knew I had to bring this skill set to the table, even though it was not part of the original scope of work. I allowed myself to lean into that spark I felt. I hand-sketched a few illustrations in Procreate for their website that felt personal and tied to the joy that comics evoke. Beyond that, I found a way to incorporate my knowledge of manga into a background pattern that pulled inspiration from nawa-ami (a traditional cross-hatching style to denote deep thought) and mixed it with the motif of fingerprints — the idea of identity and the artist’s own mark on their work. Due to my deep passion, I was able to cultivate an excellent collaborative relationship with the client, which led to a very successful launch and being invited to speak on their podcast. This experience solidified my belief that through tapping into Connection Paths, you can forge not only amazing projects but also partnerships. Try This Look at what projects you currently have and see which of the Three Connection Paths you could use to build that bond with the client or the subject matter. If you don’t see one of the Three Connection Paths aligning, then what skills or research could you bring to the table instead? Approach 3: Take Up Your Own Space The last — and arguably most important — approach to leveling up your projects is taking up your own space. I’m not referring to physical space like strong-arming those around you. What I’m referring to is the space in which designers take to be vocal about their design decisions. A lot of designers find this practice uncomfortable. Whether it stems from having not been given that space to practice as a beginner designer, higher ranking designers not leaving the room for those less vocal, or even you yourself feeling like someone else might be better suited to talk to a particular point. Don’t Retreat Similarly, some designers find themselves retreating when receiving feedback. Instead of standing behind the reasoning of their designs or asking follow-up questions, it seems easier to simply go along with the requested change in order to make the client or team member providing the feedback happy. Even if you disagree with the request, does it feel like you need to execute it just because the client — or someone you feel outranks you — told you to? You Are The Expert There is another option, one in which you can mark yourself as the design expert you are and get comfortable in the discomfort. Saying you don’t agree and explaining why helps solidify you as a strong decision-maker and confident designer. Tying it back to why you made the decision in the first place is key. Illuminating your opinions and reasoning in conversations is what will get those around you to trust in your decisions. Hiding them away or conceding to client whims isn’t going to show those around you that you have the knowledge to make the proper recommendations for a project. The Middle Ground Now, I’m not saying that you will need to always disagree with the provided feedback to show that you have a backbone. Far from it. I think there is a time and place for when you need to lean into your expertise, and a time and place for when you need to find a middle ground and/or collaborate. Collaborating with coworkers and clients lets them peek into the “why” behind the design decisions being made. Example A great example of this is a client questioning you on a particular font size, saying it feels too large and out of place. You have two options: You could say that you will make it smaller. Or you could dig deeper. If you have been paying attention thus far, you’d know that option 2. is the route I would suggest. So, instead of just changing the font size, you should ask for specifics. For example, is the type hierarchy feeling off — the relationship of that heading to the body font it is paired with? You can ask if the size feels large in other instances since perhaps this is your H2 font, so it would need to be changed across the board. Calling attention to why you chose this size using data-informed UX design, accessibility, brand, or storytelling reasons all amplify your decision-making skills before the client, so including that information here helps. If, after the discussion, the client still wants to go with changing the font size, at least you have given your reasoning and shown that you didn’t thoughtlessly make a decision — you made the design choice after taking into consideration multiple factors and putting in a lot of thought. Over time, this will build trust in you as the design expert on projects. Real-Life Example An example in which I showcased taking up my own space was from a recent project I worked on for Hilton Stories in their collaboration with Wicked. After conceptualizing a grand takeover experience complete with a storytelling undertone, one of the clients wanted to remove the page-loading animation with the idea of having more branded elements elsewhere. While most of my team was ready to execute this, I read between the lines and realized that we could solve the issue by including clear verbiage of the collaboration on the loading animation as well as adding logos and a video spot to the interior pages. By sticking up for a key piece of my designs, I was able to show that I was aligned with not only my design decisions but the major goals of the project. This solution made the clients happy and allowed for a successful launch with the loading animation that the Fueled + 10up team and I worked so hard on. Try This The next time you receive feedback, pause for a moment. Take in carefully what is being said and ask questions before responding. Analyze if it makes sense to go against the design decisions you made. If it doesn’t, tell the client why. Have that open dialogue and see where you land. This will be uncomfortable at first, but over time, it will get easier. Remember, you made your decisions for a reason. Now is the time to back up your design work and ultimately back up yourself and your decisions. So, take up your own space unapologetically. Conclusion Now that you have learned all about the three approaches, there is nothing stopping you from trialing these on your next project. From unlearning previous experiences through Reframing to tapping into your background with Connection Paths, you can lay the groundwork for how your past can be used to shape your future interactions. When taking up your own space, start small as you begin to advocate for your designs, and always try to connect to the “whys” so you instill trust in your clients and members of your design team. As Robin Williams so eloquently delivered in the Dead Poets Society, “No matter what anybody tells you, words and ideas can change the world.” In this case, you don’t need to apply it so widely as the entire world, maybe just to your workplace for now.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      An Introduction To CSS Scroll-Driven Animations: Scroll And View Progress Timelines

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        10 years after scroll-driven animations were first proposed, they’re finally here — no JavaScript, no dependencies, no libraries, just pure CSS.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        You can safely use scroll-driven animations in Chrome as of December 2024. Firefox supports them, too, though you’ll need to enable a flag. Safari? Not yet, but don’t worry — you can still offer a seamless experience across all browsers with a polyfill. Just keep in mind that adding a polyfill involves a JavaScript library, so you won’t get the same performance boost. There are plenty of valuable resources to dive into scroll-driven animations, which I’ll be linking throughout the article. My starting point was Bramus’ video tutorial, which pairs nicely with Geoff’s in-depth notes Graham that build on the tutorial. In this article, we’ll walk through the latest published version by the W3C and explore the two types of scroll-driven timelines — scroll progress timelines and view progress timelines. By the end, I hope that you are familiar with both timelines, not only being able to tell them apart but also feeling confident enough to use them in your work. Note: All demos in this article only work in Chrome 116 or later at the time of writing. Scroll Progress Timelines The scroll progress timeline links an animation’s timeline to the scroll position of a scroll container along a specific axis. So, the animation is tied directly to scrolling. As you scroll forward, so does the animation. You’ll see me refer to them as scroll-timeline animations in addition to calling them scroll progress timelines. Just as we have two types of scroll-driven animations, we have two types of scroll-timeline animations: anonymous timelines and named timelines. Anonymous scroll-timeline Let’s start with a classic example: creating a scroll progress bar at the top of a blog post to track your reading progress. See the Pen Scroll Progress Timeline example - before animation-timeline scroll() [forked] by Mariana Beldi. In this example, there’s a <div> with the ID “progress.” At the end of the CSS file, you’ll see it has a background color, a defined width and height, and it’s fixed at the top of the page. There’s also an animation that scales it from 0 to 1 along the x-axis — pretty standard if you’re familiar with CSS animations! Here’s the relevant part of the styles: #progress { /* ... */ animation: progressBar 1s linear; } @keyframes progressBar { from { transform: scaleX(0); } } The progressBar animation runs once and lasts one second with a linear timing function. Linking this animation scrolling is just a single line in CSS: animation-timeline: scroll(); No need to specify seconds for the duration — the scrolling behavior itself will dictate the timing. And that’s it! You’ve just created your first scroll-driven animation! Notice how the animation’s direction is directly tied to the scrolling direction — scroll down, and the progress indicator grows wider; scroll up, and it becomes narrower. See the Pen Scroll Progress Timeline example - animation-timeline scroll() [forked] by Mariana Beldi. scroll-timeline Property Parameters In a scroll-timeline animation, the scroll() function is used inside the animation-timeline property. It only takes two parameters: <scroller> and <axis>. <scroller> refers to the scroll container, which can be set as nearest (the default), root, or self. <axis> refers to the scroll axis, which can be block (the default), inline, x, or y. In the reading progress example above, we didn’t declare any of these because we used the defaults. But we could achieve the same result with: animation-timeline: scroll(nearest block); Here, the nearest scroll container is the root scroll of the HTML element. So, we could also write it this way instead: animation-timeline: scroll(root block); The block axis confirms that the scroll moves top to bottom in a left-to-right writing mode. If the page has a wide horizontal scroll, and we want to animate along that axis, we could use the inline or x values (depending on whether we want the scrolling direction to always be left-to-right or adapt based on the writing mode). We’ll dive into self and inline in more examples later, but the best way to learn is to play around with all the combinations, and this tool by Bramus lets you do exactly that. Spend a few minutes before we jump into the next property associated with scroll timelines. The animation-range Property The animation-range for scroll-timeline defines which part of the scrollable content controls the start and end of an animation’s progress based on the scroll position. It allows you to decide when the animation starts or ends while scrolling through the container. By default, the animation-range is set to normal, which is shorthand for the following: animation-range-start: normal; animation-range-end: normal; This translates to 0% (start) and 100% (end) in a scroll-timeline animation: animation-range: normal normal; …which is the same as: animation-range: 0% 100%; You can declare any CSS length units or even calculations. For example, let’s say I have a footer that’s 500px tall. It’s filled with banners, ads, and related posts. I don’t want the scroll progress bar to include any of that as part of the reading progress. What I want is for the animation to start at the top and end 500px before the bottom. Here we go: animation-range: 0% calc(100% - 500px); See the Pen Scroll Progress Timeline example - animation-timeline, animation-range [forked] by Mariana Beldi. Just like that, we’ve covered the key properties of scroll-timeline animations. Ready to take it a step further? Named scroll-timeline Let’s say I want to use the scroll position of a different scroll container for the same animation. The scroll-timeline-name property allows you to specify which scroll container the scroll animation should be linked to. You give it a name (a dashed-ident, e.g., --my-scroll-timeline) that maps to the scroll container you want to use. This container will then control the animation’s progress as the user scrolls through it. Next, we need to define the scroll axis for this new container by using the scroll-timeline-axis, which tells the animation which axis will trigger the motion. Here’s how it looks in the code: .my-class { /* This is my new scroll-container */ scroll-timeline-name: --my-custom-name; scroll-timeline-axis: inline; } If you omit the axis, then the default block value will be used. However, you can also use the shorthand scroll-timeline property to combine both the name and axis in a single declaration: .my-class { /* Shorthand for scroll-container with axis */ scroll-timeline: --my-custom-name inline; } I think it’s easier to understand all this with a practical example. Here’s the same progress indicator we’ve been working with, but with inline scrolling (i.e., along the x-axis): See the Pen Named Scroll Progress Timeline [forked] by Mariana Beldi. We have two animations running: A progress bar grows wider when scrolling in an inline direction. The container’s background color changes the further you scroll. The HTML structure looks like the following: <div class="gallery"> <div class="gallery-scroll-container"> <div class="gallery-progress" role="progressbar" aria-label="progress"></div> <img src="image1.svg" alt="Alt text" draggable="false" width="500"> <img src="image2.svg" alt="Alt text" draggable="false" width="500"> <img src="image3.svg" alt="Alt text" draggable="false" width="500"> </div> </div> In this case, the gallery-scroll-container has horizontal scrolling and changes its background color as you scroll. Normally, we could just use animation-timeline: scroll(self inline) to achieve this. However, we also want the gallery-progress element to use the same scroll for its animation. The gallery-progress element is the first inside gallery-scroll-container, and we will lose it when scrolling unless it’s absolutely positioned. But when we do this, the element no longer occupies space in the normal document flow, and that affects how the element behaves with its parent and siblings. We need to specify which scroll container we want it to listen to. That’s where naming the scroll container comes in handy. By giving gallery-scroll-container a scroll-timeline-name and scroll-timeline-axis, we can ensure both animations sync to the same scroll: .gallery-scroll-container { /* ... */ animation: bg steps(1); scroll-timeline: --scroller inline; } And is using that scrolling to define its own animation-timeline: .gallery-scroll-container { /* ... */ animation: bg steps(1); scroll-timeline: --scroller inline; animation-timeline: --scroller; } Now we can scale this name to the progress bar that is using a different animation but listening to the same scroll: .gallery-progress { /* ... */ animation: progressBar linear; animation-timeline: --scroller; } This allows both animations (the growing progress bar and changing background color) to follow the same scroll behavior, even though they are separate elements and animations. The timeline-scope Property What happens if we want to animate something based on the scroll position of a sibling or even a higher ancestor? This is where the timeline-scope property comes into play. It allows us to extend the scope of a scroll-timeline beyond the current element’s subtree. The value of timeline-scope must be a custom identifier, which again is a dashed-ident. Let’s illustrate this with a new example. This time, scrolling in one container runs an animation inside another container: See the Pen Scroll Driven Animations - timeline-scope [forked] by Mariana Beldi. We can play the animation on the image when scrolling the text container because they are siblings in the HTML structure: <div class="main-container"> <div class="sardinas-container"> <img ...> </div> <div class="scroll-container"> <p>Long text...</p> </div> </div> Here, only the .scroll-container has scrollable content, so let’s start by naming this: .scroll-container { /* ... */ overflow-y: scroll; scroll-timeline: --containerText; } Notice that I haven’t specified the scroll axis, as it defaults to block (vertical scrolling), and that’s the value I want. Let’s move on to the image inside the sardinas-container. We want this image to animate as we scroll through the scroll-container. I’ve added a scroll-timeline-name to its animation-timeline property: .sardinas-container img { /* ... */ animation: moveUp steps(6) both; animation-timeline: --containerText; } At this point, however, the animation still won’t work because the scroll-container is not directly related to the images. To make this work, we need to extend the scroll-timeline-name so it becomes reachable. This is done by adding the timeline-scope to the parent element (or a higher ancestor) shared by both elements: .main-container { /* ... */ timeline-scope: --containerText; } With this setup, the scroll of the scroll-container will now control the animation of the image inside the sardinas-container! Now that we’ve covered how to use timeline-scope, we’re ready to move on to the next type of scroll-driven animations, where the same properties will apply but with slight differences in how they behave. View Progress Timelines We just looked at scroll progress animations. That’s the first type of scroll-driven animation of the two. Next, we’re turning our attention to view progress animations. There’s a lot of similarities between the two! But they’re different enough to warrant their own section for us to explore how they work. You’ll see me refer to these as view-timeline animations in addition to calling them view progress animations, as they revolve around a view() function. The view progress timeline is the second type of type of scroll-driven animation that we’re looking at. It tracks an element as it enters or exits the scrollport (the visible area of the scrollable content). This behavior is quite similar to how an IntersectionObserver works in JavaScript but can be done entirely in CSS. We have anonymous and named view progress timelines, just as we have anonymous and named scroll progress animations. Let’s unpack those. Anonymous View Timeline Here’s a simple example to help us see the basic idea of anonymous view timelines. Notice how the image fades into view when you scroll down to a certain point on the page: See the Pen View Timeline Animation - view() [forked] by Mariana Beldi. Let’s say we want to animate an image that fades in as it appears in the scrollport. The image’s opacity will go from 0 to 1. This is how you might write that same animation in classic CSS using @keyframes: img { /* ... */ animation: fadeIn 1s; } @keyframes fadeIn { from { opacity: 0; } to { opacity: 1; } } That’s great, but we want the image to fadeIn when it’s in view. Otherwise, the animation is sort of like a tree that falls in a forest with no one there to witness it… did the animation ever happen? We’ll never know! We have a view() function that makes this a view progress animation with a single line of CSS: img { /* ... */ animation: fadeIn; animation-timeline: view(); } And notice how we no longer need to declare an animation-duration like we did in classic CSS. The animation is no longer tied by time but by space. The animation is triggered as the image becomes visible in the scrollport. View Timeline Parameters Just like the scroll-timeline property, the view-timeline property accepts parameters that allow for more customization: animation-timeline: view( ); <inset> Controls when the animation starts and ends relative to the element’s visibility within the scrollport. It defines the margin between the edges of the scrollport and the element being tracked. The default value is auto, but it can also take length percentages as well as start and end values. <axis> This is similar to the scroll-timeline’s axis parameter. It defines which axis (horizontal or vertical) the animation is tied to. The default is block, which means it tracks the vertical movement. You can also use inline to track horizontal movement or simple x or y. Here’s an example that uses both inset and axis to customize when and how the animation starts: img { animation-timeline: view(20% block); } In this case: The animation starts when the image is 20% visible in the scrollport. The animation is triggered by vertical scrolling (block axis). Parallax Effect With the view() function, it’s also easy to create parallax effects by simply adjusting the animation properties. For example, you can have an element move or scale as it enters the scrollport without any JavaScript: img { animation: parallaxMove 1s; animation-timeline: view(); } @keyframes parallaxMove { to { transform: translateY(-50px); } } This makes it incredibly simple to create dynamic and engaging scroll animations with just a few lines of CSS. See the Pen Parallax effect with CSS Scroll driven animations - view() [forked] by Mariana Beldi. The animation-range Property Using the CSS animation-range property with view timelines defines how much of an element’s visibility within the scrollport controls the start and end points of the animation’s progress. This can be used to fine-tune when the animation begins and ends based on the element’s visibility in the viewport. While the default value is normal, in view timelines, it translates to tracking the full visibility of the element from the moment it starts entering the scrollport until it fully leaves. This is represented by the following: animation-range: normal normal; /* Equivalent to */ animation-range: cover 0% cover 100%; Or, more simply: animation-range: cover; There are six possible values or timeline-range-names: cover Tracks the full visibility of the element, from when it starts entering the scrollport to when it completely leaves it. contain Tracks when the element is fully visible inside the scrollport, from the moment it’s fully contained until it no longer is. entry Tracks the element from the point it starts entering the scrollport until it’s fully inside. exit Tracks the element from the point it starts, leaving the scrollport until it’s fully outside. entry-crossing Tracks the element as it crosses the starting edge of the scrollport, from start to full crossing. exit-crossing Tracks the element as it crosses the end edge of the scrollport, from start to full crossing. You can mix different timeline-range-names to control the start and end points of the animation range. For example, you could make the animation start when the element enters the scrollport and end when it exits: animation-range: entry exit; You can also combine these values with percentages to define more custom behavior, such as starting the animation halfway through the element’s entry and ending it halfway through its exit: animation-range: entry 50% exit 50%; Exploring all these values and combinations is best done interactively. Tools like Bramus’ view-timeline range visualizer make it easier to understand. Target Range Inside @keyframes One of the powerful features of timeline-range-names is their ability to be used inside @keyframes: See the Pen target range inside @keyframes - view-timeline, timeline-range-name [forked] by Mariana Beldi. Two different animations are happening in that demo: slideIn When the element enters the scrollport, it scales up and becomes visible. slideOut When the element leaves, it scales down and fades out. @keyframes slideIn { from { transform: scale(.8) translateY(100px); opacity: 0; } to { transform: scale(1) translateY(0); opacity: 1; } } @keyframes slideOut { from { transform: scale(1) translateY(0); opacity: 1; } to { transform: scale(.8) translateY(-100px); opacity: 0 } } The new thing is that now we can merge these two animations using the entry and exit timeline-range-names, simplifying it into one animation that handles both cases: @keyframes slideInOut { /* Animation for when the element enters the scrollport */ entry 0% { transform: scale(.8) translateY(100px); opacity: 0; } entry 100% { transform: scale(1) translateY(0); opacity: 1; } /* Animation for when the element exits the scrollport */ exit 0% { transform: scale(1) translateY(0); opacity: 1; } exit 100% { transform: scale(.8) translateY(-100px); opacity: 0; } } entry 0% Defines the state of the element at the beginning of its entry into the scrollport (scaled down and transparent). entry 100% Defines the state when the element has fully entered the scrollport (fully visible and scaled up). exit 0% Starts tracking the element as it begins to leave the scrollport (visible and scaled up). exit 100% Defines the state when the element has fully left the scrollport (scaled down and transparent). This approach allows us to animate the element’s behavior smoothly as it both enters and leaves the scrollport, all within a single @keyframes block. Named view-timeline And timeline-scope The concept of using view-timeline with named timelines and linking them across different elements can truly expand the possibilities for scroll-driven animations. In this case, we are linking the scroll-driven animation of images with the animations of unrelated paragraphs in the DOM structure by using a named view-timeline and timeline-scope. The view-timeline property works similarly to the scroll-timeline property. It’s the shorthand for declaring the view-timeline-name and view-timeline-axis properties in one line. However, the difference from scroll-timeline is that we can link the animation of an element when the linked elements enter the scrollport. I took the previous demo and added an animation to the paragraphs so you can see how the opacity of the text is animated when scrolling the images on the left: See the Pen View-timeline, timeline-scope [forked] by Mariana Beldi. This one looks a bit verbose, but I found it hard to come up with a better example to show the power of it. Each image in the vertical scroll container is assigned a named view-timeline with a unique identifier: .vertical-scroll-container img:nth-of-type(1) { view-timeline: --one; } .vertical-scroll-container img:nth-of-type(2) { view-timeline: --two; } .vertical-scroll-container img:nth-of-type(3) { view-timeline: --three; } .vertical-scroll-container img:nth-of-type(4) { view-timeline: --four; } This makes the scroll timeline of each image have its own custom name, such as --one for the first image, --two for the second, and so on. Next, we connect the animations of the paragraphs to the named timelines of the images. The corresponding paragraph should animate when the images enter the scrollport: .vertical-text p:nth-of-type(1) { animation-timeline: --one; } .vertical-text p:nth-of-type(2) { animation-timeline: --two; } .vertical-text p:nth-of-type(3) { animation-timeline: --three; } .vertical-text p:nth-of-type(4) { animation-timeline: --four; } However, since the images and paragraphs are not directly related in the DOM, we need to declare a timeline-scope on their common ancestor. This ensures that the named timelines (--one, --two, and so on) can be referenced and shared between the elements: .porto { /* ... */ timeline-scope: --one, --two, --three, --four; } By declaring the timeline-scope with all the named timelines (--one, —two, --three, --four), both the images and the paragraphs can participate in the same scroll-timeline logic, despite being in separate parts of the DOM tree. Final Notes We’ve covered the vast majority of what’s currently defined in the CSS Scroll-Driven Animations Module Leve 1 specification today in December 2024. But I want to highlight a few key takeaways that helped me better understand these new rules that you may not get directly from the spec: Scroll container essentials It may seem obvious, but a scroll container is necessary for scroll-driven animations to work. Issues often arise when elements like text or containers are resized or when animations are tested on larger screens, causing the scrollable area to disappear. Impact of position: absolute Using absolute positioning can sometimes interfere with the intended behavior of scroll-driven animations. The relationship between elements and their parent elements gets tricky when position: absolute is applied. Tracking an element’s initial state The browser evaluates the element’s state before any transformations (like translate) are applied. This affects when animations, particularly view timelines, begin. Your animation might trigger earlier or later than expected due to the initial state. Avoid hiding overflow Using overflow: hidden can disrupt the scroll-seeking mechanism in scroll-driven animations. The recommended solution is to switch to overflow: clip. Bramus has a great article about this and a video from Kevin Powell also suggests that we may no longer need overflow: hidden. Performance For the best results, stick to animating GPU-friendly properties like transforms, opacity, and some filters. These skip the heavy lifting of recalculating layout and repainting. On the other hand, animating things like width, height, or box-shadow can slow things down since they require re-rendering. Bramus mentioned that soon, more properties — like background-color, clip-path, width, and height — will be animatable on the compositor, making the performance even better. Use will-change wisely Leverage this property to promote elements to the GPU, but use it sparingly. Overusing will-change can lead to excessive memory usage since the browser reserves resources even if the animations don’t frequently change. The order matters If you are using the animation shorthand, always place the animation-timeline after it. Progressive enhancement and accessibility Combine media queries for reduced motion preferences with the @supports rule to ensure animations only apply when the user has no motion restrictions, and the browser supports them. For example: @media screen and (prefers-reduce-motion: no-preference) { @supports ((animation-timeline: scroll()) and (animation-range: 0% 100%)) { .my-class { animation: moveCard linear both; animation-timeline: view(); } } } My main struggle while trying to build the demos was more about CSS itself than the scroll animations. Sometimes, building the layout and generating the scroll was more difficult than applying the scroll animation. Also, some things that confused me at the beginning as the spec keeps evolving, and some of these are not there anymore (remember, it has been under development for more than five years now!): x and y axes These used to be called the “horizontal” and “vertical” axes, and while Firefox may still support the old terminology, it has been updated. Old @scroll-timeline syntax In the past, @scroll-timeline was used to declare scroll timelines, but this has changed in the most recent version of the spec. Scroll-driven vs. scroll-linked animations Scroll-driven animations were originally called scroll-linked animations. If you come across this older term in articles, double-check whether the content has been updated to reflect the latest spec, particularly with features like timeline-scope. Resources All demos from this article can be found in this collection, and I might include more as I experiment further. A collection of demos from CodePen that I find interesting (send me yours, and I’ll include it!) This GitHub repo is where you can report issues or join discussions about scroll-driven animations. Demos, tools, videos, and (even) more information from Bramus Google Chrome video tutorial

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        Mastering SVG Arcs

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          SVG arcs demystified! Akshay Gupta explains how to master radii, rotation, and arc direction to create stunning curves. Make arcs a powerful part of your SVG toolkit for creating more dynamic, intricate designs with confidence.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          So, I love drawing birds with code. Inspired by my brother’s love for birdwatching, I admire the uniqueness of their feathers, colors, and sounds. But what I notice most is the way their bodies curve and different birds can have dramatically different curves! So, I took my love for drawing with SVG graphics and used it to experiment with bird shapes. Over time, I’ve drawn enough to become incredibly adept at working with arc shapes. Here are a few of my recent works. Inspired by designs I came across on Dribbble, I created my versions with code. You can browse through the code for each on my CodePen. But before we dive into creating curves with arcs, please pause here and check out Myriam Frisano’s recent article, “SVG Coding Examples: Useful Recipes For Writing Vectors By Hand.” It’s an excellent primer to the SVG syntax and it will give you solid context heading into the concepts we’re covering here when it comes to mastering SVG arcs. A Quick SVG Refresher You probably know that SVGs are crisp, infinitely scalable illustrations without pixelated degradation — vectors for the win! What you might not know is that few developers write SVG code. Why? Well, the syntax looks complicated and unfamiliar compared to, say, HTML. But trust me, once you break it down, it’s not only possible to hand-code SVG but also quite a bit of fun. Let’s make sure you’re up to speed on the SVG viewBox because it’s a key concept when it comes to the scalable part of *SVG. We’ll use the analogy of a camera, lens, and canvas to explain this concept. Think of your browser window as a camera and the SVG viewBox as the camera lens focusing on the painting of a bird you’ve created (the SVG). Imagine the painting on a large canvas that may stretch far beyond what the camera captures. The viewBox defines which part of this canvas is visible through the camera. Let’s say we have an SVG element that we’re sizing at 600px square with width and height attributes directly on the <svg> element. <svg width="600px" height="600px"> Let’s turn our attention to the viewBox attribute: <svg width="600px" height="600px" viewBox="-300 -300 600 600"> The viewBox attribute defines the internal coordinate system for the SVG, with four values mapping to the SVG’s x, y, width, and height in that order. Here’s how this relates to our analogy: Camera Position and Size The -300, -300 represents the camera lens’ left and top edge position. Meanwhile, 600 x 600 is like the camera’s frame size, showing a specific portion of that space. Unchanging Canvas Size Changing the x and y values adjusts where the camera points, and width and height govern how much of the canvas it frames. It doesn’t resize the actual canvas (the SVG element itself, which remains at 600×600 pixels). No matter where the camera is positioned or zoomed, the canvas itself remains fixed. So, when you adjust the viewBox coordinates, you’re simply choosing a new area of the canvas to focus on without resizing the canvas itself. This lets you control the visible area without changing the SVG’s actual display dimensions. You now have the context you need to learn how to work with <path> elements in SVG, which is where we start working with arcs! The <path> Element We have an <svg> element. And we’re viewing the element’s contents through the “lens” of a viewBox. A <path> allows us to draw shapes. We have other elements for drawing shapes — namely <circle>, <line>, and <polygon> — but imagine being restricted to strict geometrical shapes as an artist. That’s where the custom <path> element comes in. It’s used to draw complex shapes that cannot be created with the basic ones. Think of <path> as a flexible container that lets you mix and match different drawing commands. With a single <path>, you can combine multiple drawing commands into one smooth, elegant design. Today, we’re focusing on a super specific path command: arcs. In other words, what we’re doing is drawing arc shapes with <path>. Here’s a quick, no-frills example that places a <path> inside the <svg> example we looked at earlier: <svg width="600px" height="600px" viewBox="-300 -300 600 600"> <path d="M 0 0 A 100 100 0 1 1 200 0" fill="transparent" stroke="black" stroke-width="24" /> </svg> Let’s take this information and start playing with values to see how it behaves. Visualizing The Possibilities Again, if this is the <path> we’re starting with: <path d="M 0 0 A 100 100 0 1 1 200 0"/> Then, we can manipulate it in myriad ways. Mathematically speaking, you can create an infinite number of arcs between any two points by adjusting the parameters. Here are a few variations of an arc that we get when all we do is change the arc’s endpoints in the X (<ex>) and Y (<ey>) directions. See the Pen Arc Possibilities b/w 2 points [forked] by akshaygpt. Or, let’s control the arc’s width and height by updating its radius in the X direction (<rx>) and the Y direction (<ry>). If we play around with the <rx> value, we can manipulate the arc’s height: See the Pen Rx [forked] by akshaygpt. Similarly, we can manipulate the arc’s width by updating the <ry> value: See the Pen Ry [forked] by akshaygpt. Let’s see what happens when we rotate the arc along its X-axis (<rotation>). This parameter rotates the arc’s ellipse around its center. It won’t affect circles, but it’s a game-changer for ellipses. See the Pen x-axis-rotation [forked] by akshaygpt. Even with a fixed set of endpoints and radii (<rx> and <ry>), and a given angle of rotation, four distinct arcs can connect them. That’s because we have the <arc> flag value that can be one of two values, as well as the <sweep> flag that is also one of two values. Two boolean values, each with two arguments, give us four distinct possibilities. See the Pen 4 cases [forked] by akshaygpt. And lastly, adjusting the arc’s endpoint along the X (<ex>) and Y (<ey>) directions shifts the arc’s location without changing the overall shape. See the Pen endx, endy [forked] by akshaygpt. Wrapping Up And there you have it, SVG arcs demystified! Whether you’re manipulating radii, rotation, or arc direction, you now have all the tools to master these beautiful curves. With practice, arcs will become just another part of your SVG toolkit, one that gives you the power to create more dynamic, intricate designs with confidence. So keep playing, keep experimenting, and soon you’ll be bending arcs like a pro — making your SVGs not just functional but beautifully artistic. If you enjoyed this dive into arcs, drop a like or share it with your friends. Let’s keep pushing the boundaries of what SVG can do!

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          The Importance Of Graceful Degradation In Accessible Interface Design

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            Few things are as frustrating to a user as when a site won’t respond. Unfortunately, it’s also an all-too-common scenario. Many websites and apps depend on so many elements that one of any number of errors could cause the whole thing to fail. As prevalent as such instances may be, they’re preventable through the practice of graceful degradation.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            Graceful degradation is a design approach that ensures the basics of a website will still function even if specific individual parts of it stop working. The approach removes single points of failure: just because one thing stops working doesn’t mean the system as a whole fails. A site following this principle fails in pieces instead of all at once, so the most important features remain available when some components encounter an error. The idea or the concept of single points of failure is well known in the manufacturing sector. It’s one of the most common resilience strategies in manufacturing and supply chain operations. A factory with multiple sources of material can keep working even when one supplier becomes unavailable. However, it’s become increasingly crucial to web development as user expectations around availability and functionality rise. Data center redundancy is a common example of graceful degradation in web development. By using multiple server components, websites ensure they’ll stay up when one or more servers fail. In a design context, it may look like guaranteeing the lack of support for a given feature in a user’s browser or device doesn’t render an app unusable. Escalators are a familiar real-world example of the same concept. When they stop working, they can still get people from one floor to the next by acting as stairs. They may not be as functional as they normally are, but they’re not entirely useless. The BBC News webpage is a good example of graceful degradation in web design. As this screenshot shows, the site prioritizes loading navigation and the text within a news story over images. Consequently, slow speeds or old, incompatible browser plugins may make pictures unavailable, but the site’s core function — sharing the news — is still accessible. In contrast, the Adobe Express website is an example of what happens without graceful degradation. Instead of making some features unavailable or dropping load times, the entire site is inaccessible on some browsers. Consequently, users have to update or switch software to use the web app, which isn’t great for accessibility. Graceful Degradation vs. Progressive Enhancement The graceful degradation approach acts as the opposite of progressive enhancement — an approach in which a designer builds the basics of a website and progressively adds features that are turned on only if a browser is capable of running them. Each layer of features is turned off by default, allowing for one seamless user experience designed to work for everyone. There is much debate between designers about whether graceful degradation or progressive enhancement is the best way to build site functionality. In reality, though, both are important. Each method has unique pros and cons, so the two can complement each other to provide the most resilience. Progressive enhancement is a good strategy when building a new site or app because you ensure a functional experience for everyone from the start. However, new standards and issues can emerge in the future, which is where graceful degradation comes in. This approach helps you adjust an existing website to comply with new accessibility standards or resolve a compatibility problem you didn’t notice earlier. Focusing solely on one design principle or the other will limit accessibility. Progressive enhancement alone struggles to account for post-launch functionality issues, while graceful degradation alone may fail to provide the most feature-rich baseline experience. Combining both will produce the best result. How Graceful Degradation Impacts Accessibility Ensuring your site or app remains functional is crucial for accessibility. When core functions become unavailable, the platform is no longer accessible to anyone. On a smaller scale, if features like text-to-speech readers or video closed captioning stop working, users with sight difficulties may be unable to enjoy the site. Graceful degradation’s impact on accessibility is all the larger when considering varying device capabilities. As the average person spends 3.6 hours each day on their phone, failing to ensure a site supports less powerful mobile browsers will alienate a considerable chunk of your audience. Even if some complex functions may not work on mobile, sacrificing those to keep the bulk of the website available on phones ensures broader accessibility. Outdated browsers are another common accessibility issue you can address with graceful degradation. Consider this example from Fairleigh Dickinson University about Adobe Flash, which most modern browsers no longer support. Software still using Flash cannot use the multi-factor authentication feature in question. As a result, users with older programs can’t log in. Graceful degradation may compromise by making some functionality unavailable to Flash-supporting browsers while still allowing general access. That way, people don’t need to upgrade to use the service. How to Incorporate Graceful Degradation Into Your Site Graceful degradation removes technological barriers to accessibility. In a broader sense, it also keeps your site or app running at all times, even amid unforeseen technical difficulties. While there are many ways you can achieve that, here are some general best practices to follow. Identify Mission-Critical Functions The first step in ensuring graceful degradation is determining what your core functions are. You can only guarantee the availability of mission-critical features once you know what’s essential and what isn’t. Review your user data to see what your audience interacts with most — these are generally elements worth prioritizing. Anything related to site security, transactions, and readability is also crucial. Infrequently used features or elements like video players and interactive maps are nice to have but okay to sacrifice if you must to ensure mission-critical components remain available. Build Redundancy Once you’ve categorized site functions by criticality, you can ensure redundancy for the most important ones. That may mean replicating elements in a few forms to work on varying browsers or devices. Alternatively, you could provide multiple services to carry out important functions, like supporting alternate payment methods or providing both video and text versions of content. Remember that redundancy applies to the hardware your platform runs on, too. The Uptime Institute classifies data centers into tiers, which you can use to determine what redundant systems you need. Similarly, make sure you can run your site on multiple servers to avoid a crash should one go down. Accommodate All Browsers Remember that graceful degradation is also about supporting software and hardware of varying capabilities. One of the most important considerations under that umbrella for web design is to accommodate outdated browsers. While mobile devices don’t support Flash, some older versions of desktop browsers still use it. You can work with both by avoiding Flash — you can often use HTML5 instead — but not requiring users to have a non-Flash-supporting browser. Similarly, you can offer low-bandwidth, simple alternatives to any features that take up considerable processing power to keep things accessible on older systems. Remember to pay attention to newer software’s security settings, too. Error messages like this one a Microsoft user posted about can appear if a site does not support some browsers’ updated security protocols. Always keep up with updates from popular platforms like Chrome and Safari to meet these standards and avoid such access issues. Employ Load Balancing and Caching Load balancing is another crucial step in graceful degradation. Many cloud services automatically distribute traffic between server resources to prevent overloading. Enabling this also ensures that requests can be processed on a different part of the system if another fails. Caching is similar. By storing critical data, you build a fallback plan if an external service or application program interface (API) doesn’t work. When the API doesn’t respond, you can load the cached data instead. As a result, caches significantly reduce latency in many cases, but you should be aware that you can’t cache everything. Focus on the most critical functions. Test Before Publishing Finally, be sure to test your website for accessibility issues before taking it live. Access it from multiple devices, including various browser versions. See if you can run it on a single server to test its ability to balance loads. You likely won’t discover all possible errors in testing, but it’s better to catch some than none. Remember to test your site’s functionality before any updates or redesigns, too. Getting Started With Graceful Degradation Designers, both big and small, can start their graceful degradation journey by tweaking some settings with their web hosting service. AWS offers guidance for managing failures you can use to build degradation into your site’s architecture. Hosting providers should also allow you to upgrade your storage plan and configure your server settings to provide redundancy and balance loads. Businesses large enough to run their own data centers should install redundant server capacity and uninterruptible power supplies to keep things running. Smaller organizations can instead rely on their code, using semantic HTML to keep it simple enough for multiple browsers. Programming nonessential things like images and videos to stop when bandwidth is low will also help. Virtualization systems like Kubernetes are also useful as a way to scale site capacity and help load elements separately from one another to maintain accessibility. Testing tools like BrowserStack, WAVE, and CSS HTML Validator can assist you by revealing if your site has functional issues on some browsers or for certain users. At its core, web accessibility is about ensuring a platform works as intended for all people. While design features may be the most obvious part of that goal, technical defenses also play a role. A site is only accessible when it works, so you must keep it functional, even when unexpected hiccups occur. Graceful degradation is not a perfect solution, but it prevents a small issue from becoming a larger one. Following these five steps to implement it on your website or app will ensure that your work in creating an accessible design doesn’t go to waste.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            Creating An Effective Multistep Form For Better User Experience

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              Forms are already notoriously tough to customize and style — to the extent that we’re already starting to see new ideas for more flexible control. But what we don’t often discuss is designing good-form experiences beyond validation. That’s what Jima Victor discusses in this article, focusing specifically on creating multi-step forms that involve navigation between sections.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              For a multistep form, planning involves structuring questions logically across steps, grouping similar questions, and minimizing the number of steps and the amount of required information for each step. Whatever makes each step focused and manageable is what should be aimed for. In this tutorial, we will create a multistep form for a job application. Here are the details we are going to be requesting from the applicant at each step: Personal Information Collects applicant’s name, email, and phone number. Work Experience Collects the applicant’s most recent company, job title, and years of experience. Skills & Qualifications The applicant lists their skills and selects their highest degree. Review & Submit This step is not going to collect any information. Instead, it provides an opportunity for the applicant to go back and review the information entered in the previous steps of the form before submitting it. You can think of structuring these questions as a digital way of getting to know somebody. You can’t meet someone for the first time and ask them about their work experience without first asking for their name. Based on the steps we have above, this is what the body of our HTML with our form should look like. First, the main <form> element: <form id="jobApplicationForm"> <!-- Step 1: Personal Information --> <!-- Step 2: Work Experience --> <!-- Step 3: Skills & Qualifications --> <!-- Step 4: Review & Submit --> </form> Step 1 is for filling in personal information, like the applicant’s name, email address, and phone number: <form id="jobApplicationForm"> <!-- Step 1: Personal Information --> <fieldset class="step" id="step-1"> <legend id="step1Label">Step 1: Personal Information</legend> <label for="name">Full Name</label> <input type="text" id="name" name="name" required /> <label for="email">Email Address</label> <input type="email" id="email" name="email" required /> <label for="phone">Phone Number</label> <input type="tel" id="phone" name="phone" required /> </fieldset> <!-- Step 2: Work Experience --> <!-- Step 3: Skills & Qualifications --> <!-- Step 4: Review & Submit --> </form> Once the applicant completes the first step, we’ll navigate them to Step 2, focusing on their work experience so that we can collect information like their most recent company, job title, and years of experience. We’ll tack on a new <fieldset> with those inputs: <form id="jobApplicationForm"> <!-- Step 1: Personal Information --> <!-- Step 2: Work Experience --> <fieldset class="step" id="step-2" hidden> <legend id="step2Label">Step 2: Work Experience</legend> <label for="company">Most Recent Company</label> <input type="text" id="company" name="company" required /> <label for="jobTitle">Job Title</label> <input type="text" id="jobTitle" name="jobTitle" required /> <label for="yearsExperience">Years of Experience</label> <input type="number" id="yearsExperience" name="yearsExperience" min="0" required /> </fieldset> <!-- Step 3: Skills & Qualifications --> <!-- Step 4: Review & Submit --> </form> Step 3 is all about the applicant listing their skills and qualifications for the job they’re applying for: <form id="jobApplicationForm"> <!-- Step 1: Personal Information --> <!-- Step 2: Work Experience --> <!-- Step 3: Skills & Qualifications --> <fieldset class="step" id="step-3" hidden> <legend id="step3Label">Step 3: Skills & Qualifications</legend> <label for="skills">Skill(s)</label> <textarea id="skills" name="skills" rows="4" required></textarea> <label for="highestDegree">Degree Obtained (Highest)</label> <select id="highestDegree" name="highestDegree" required> <option value="">Select Degree</option> <option value="highschool">High School Diploma</option> <option value="bachelor">Bachelor's Degree</option> <option value="master">Master's Degree</option> <option value="phd">Ph.D.</option> </select> </fieldset> <!-- Step 4: Review & Submit --> <fieldset class="step" id="step-4" hidden> <legend id="step4Label">Step 4: Review & Submit</legend> <p>Review your information before submitting the application.</p> <button type="submit">Submit Application</button> </fieldset> </form> And, finally, we’ll allow the applicant to review their information before submitting it: <form id="jobApplicationForm"> <!-- Step 1: Personal Information --> <!-- Step 2: Work Experience --> <!-- Step 3: Skills & Qualifications --> <!-- Step 4: Review & Submit --> <fieldset class="step" id="step-4" hidden> <legend id="step4Label">Step 4: Review & Submit</legend> <p>Review your information before submitting the application.</p> <button type="submit">Submit Application</button> </fieldset> </form> Notice: We’ve added a hidden attribute to every fieldset element but the first one. This ensures that the user sees only the first step. Once they are done with the first step, they can proceed to fill out their work experience on the second step by clicking a navigational button. We’ll add this button later on. Adding Styles To keep things focused, we’re not going to be emphasizing the styles in this tutorial. What we’ll do to keep things simple is leverage the Simple.css style framework to get the form in good shape for the rest of the tutorial. If you’re following along, we can include Simple’s styles in the document <head>: <link rel="stylesheet" href="https://cdn.simplecss.org/simple.min.css" /> And from there, go ahead and create a style.css file with the following styles that I’ve folded up. <details> <summary>View CSS</summary> body { min-height: 100vh; display: flex; align-items: center; justify-content: center; } main { padding: 0 30px; } h1 { font-size: 1.8rem; text-align: center; } .stepper { display: flex; justify-content: flex-end; padding-right: 10px; } form { box-shadow: 0px 0px 6px 2px rgba(0, 0, 0, 0.2); padding: 12px; } input, textarea, select { outline: none; } input:valid, textarea:valid, select:valid, input:focus:valid, textarea:focus:valid, select:focus:valid { border-color: green; } input:focus:invalid, textarea:focus:invalid, select:focus:invalid { border: 1px solid red; } </details> Form Navigation And Validation An easy way to ruin the user experience for a multi-step form is to wait until the user gets to the last step in the form before letting them know of any error they made along the way. Each step of the form should be validated for errors before moving on to the next step, and descriptive error messages should be displayed to enable users to understand what is wrong and how to fix it. Now, the only part of our form that is visible is the first step. To complete the form, users need to be able to navigate to the other steps. We are going to use several buttons to pull this off. The first step is going to have a Next button. The second and third steps are going to have both a Previous and a Next button, and the fourth step is going to have a Previous and a Submit button. <form id="jobApplicationForm"> <!-- Step 1: Personal Information --> <fieldset> <!-- ... --> <button type="button" class="next" onclick="nextStep()">Next</button> </fieldset> <!-- Step 2: Work Experience --> <fieldset> <!-- ... --> <button type="button" class="previous" onclick="previousStep()">Previous</button> <button type="button" class="next" onclick="nextStep()">Next</button> </fieldset> <!-- Step 3: Skills & Qualifications --> <fieldset> <!-- ... --> <button type="button" class="previous" onclick="previousStep()">Previous</button> <button type="button" class="next" onclick="nextStep()">Next</button> </fieldset> <!-- Step 4: Review & Submit --> <fieldset> <!-- ... --> <button type="button" class="previous" onclick="previousStep()">Previous</button> <button type="submit">Submit Application</button> </fieldset> </form> Notice: We’ve added onclick attributes to the Previous and Next buttons to link them to their respective JavaScript functions: previousStep() and nextStep(). The “Next” Button The nextStep() function is linked to the Next button. Whenever the user clicks the Next button, the nextStep() function will first check to ensure that all the fields for whatever step the user is on have been filled out correctly before moving on to the next step. If the fields haven’t been filled correctly, it displays some error messages, letting the user know that they’ve done something wrong and informing them what to do to make the errors go away. Before we go into the implementation of the nextStep function, there are certain variables we need to define because they will be needed in the function. First, we need the input fields from the DOM so we can run checks on them to make sure they are valid. // Step 1 fields const name = document.getElementById("name"); const email = document.getElementById("email"); const phone = document.getElementById("phone"); // Step 2 fields const company = document.getElementById("company"); const jobTitle = document.getElementById("jobTitle"); const yearsExperience = document.getElementById("yearsExperience"); // Step 3 fields const skills = document.getElementById("skills"); const highestDegree = document.getElementById("highestDegree"); Then, we’re going to need an array to store our error messages. let errorMsgs = []; Also, we would need an element in the DOM where we can insert those error messages after they’ve been generated. This element should be placed in the HTML just below the last fieldset closing tag: <div id="errorMessages" style="color: rgb(253, 67, 67)"></div> Add the above div to the JavaScript code using the following line: const errorMessagesDiv = document.getElementById("errorMessages"); And finally, we need a variable to keep track of the current step. let currentStep = 1; Now that we have all our variables in place, here’s the implementation of the nextstep() function: function nextStep() { errorMsgs = []; errorMessagesDiv.innerText = ""; switch (currentStep) { case 1: addValidationErrors(name, email, phone); validateStep(errorMsgs); break; case 2: addValidationErrors(company, jobTitle, yearsExperience); validateStep(errorMsgs); break; case 3: addValidationErrors(skills, highestDegree); validateStep(errorMsgs); break; } } The moment the Next button is pressed, our code first checks which step the user is currently on, and based on this information, it validates the data for that specific step by calling the addValidationErrors() function. If there are errors, we display them. Then, the form calls the validateStep() function to verify that there are no errors before moving on to the next step. If there are errors, it prevents the user from going on to the next step. Whenever the nextStep() function runs, the error messages are cleared first to avoid appending errors from a different step to existing errors or re-adding existing error messages when the addValidationErrors function runs. The addValidationErrors function is called for each step using the fields for that step as arguments. Here’s how the addValidationErrors function is implemented: function addValidationErrors(fieldOne, fieldTwo, fieldThree = undefined) { if (!fieldOne.checkValidity()) { const label = document.querySelector(label[for="${fieldOne.id}"]); errorMsgs.push(Please Enter A Valid ${label.textContent}); } if (!fieldTwo.checkValidity()) { const label = document.querySelector(label[for="${fieldTwo.id}"]); errorMsgs.push(Please Enter A Valid ${label.textContent}); } if (fieldThree && !fieldThree.checkValidity()) { const label = document.querySelector(label[for="${fieldThree.id}"]); errorMsgs.push(Please Enter A Valid ${label.textContent}); } if (errorMsgs.length > 0) { errorMessagesDiv.innerText = errorMsgs.join("\n"); } } This is how the validateStep() function is defined: function validateStep(errorMsgs) { if (errorMsgs.length === 0) { showStep(currentStep + 1); } } The validateStep() function checks for errors. If there are none, it proceeds to the next step with the help of the showStep() function. function showStep(step) { steps.forEach((el, index) => { el.hidden = index + 1 !== step; }); currentStep = step; } The showStep() function requires the four fieldsets in the DOM. Add the following line to the top of the JavaScript code to make the fieldsets available: const steps = document.querySelectorAll(".step"); What the showStep() function does is to go through all the fieldsets in our form and hide whatever fieldset is not equal to the one we’re navigating to. Then, it updates the currentStep variable to be equal to the step we’re navigating to. The “Previous” Button The previousStep() function is linked to the Previous button. Whenever the previous button is clicked, similarly to the nextStep function, the error messages are also cleared from the page, and navigation is also handled by the showStep function. function previousStep() { errorMessagesDiv.innerText = ""; showStep(currentStep - 1); } Whenever the showStep() function is called with “currentStep - 1” as an argument (as in this case), we go back to the previous step, while moving to the next step happens by calling the showStep() function with “currentStep + 1" as an argument (as in the case of the validateStep() function). Improving User Experience With Visual Cues One other way of improving the user experience for a multi-step form, is by integrating visual cues, things that will give users feedback on the process they are on. These things can include a progress indicator or a stepper to help the user know the exact step they are on. Integrating A Stepper To integrate a stepper into our form (sort of like this one from Material Design), the first thing we need to do is add it to the HTML just below the opening <form> tag. <form id="jobApplicationForm"> <div class="stepper"> <span><span class="currentStep">1</span>/4</span> </div> <!-- ... --> </form> Next, we need to query the part of the stepper that will represent the current step. This is the span tag with the class name of currentStep. const currentStepDiv = document.querySelector(".currentStep"); Now, we need to update the stepper value whenever the previous or next buttons are clicked. To do this, we need to update the showStep() function by appending the following line to it: currentStepDiv.innerText = currentStep; This line is added to the showStep() function because the showStep() function is responsible for navigating between steps and updating the currentStep variable. So, whenever the currentStep variable is updated, the currentStepDiv should also be updated to reflect that change. Storing And Retrieving User Data One major way we can improve the form’s user experience is by storing user data in the browser. Multistep forms are usually long and require users to enter a lot of information about themselves. Imagine a user filling out 95% of a form, then accidentally hitting the F5 button on their keyboard and losing all their progress. That would be a really bad experience for the user. Using localStorage, we can store user information as soon as it is entered and retrieve it as soon as the DOM content is loaded, so users can always continue filling out their forms from wherever they left off. To add this feature to our forms, we can begin by saving the user’s information as soon as it is typed. This can be achieved using the input event. Before adding the input event listener, get the form element from the DOM: const form = document.getElementById("jobApplicationForm"); Now we can add the input event listener: // Save data on each input event form.addEventListener("input", () => { const formData = { name: document.getElementById("name").value, email: document.getElementById("email").value, phone: document.getElementById("phone").value, company: document.getElementById("company").value, jobTitle: document.getElementById("jobTitle").value, yearsExperience: document.getElementById("yearsExperience").value, skills: document.getElementById("skills").value, highestDegree: document.getElementById("highestDegree").value, }; localStorage.setItem("formData", JSON.stringify(formData)); }); Next, we need to add some code to help us retrieve the user data once the DOM content is loaded. window.addEventListener("DOMContentLoaded", () => { const savedData = JSON.parse(localStorage.getItem("formData")); if (savedData) { document.getElementById("name").value = savedData.name || ""; document.getElementById("email").value = savedData.email || ""; document.getElementById("phone").value = savedData.phone || ""; document.getElementById("company").value = savedData.company || ""; document.getElementById("jobTitle").value = savedData.jobTitle || ""; document.getElementById("yearsExperience").value = savedData.yearsExperience || ""; document.getElementById("skills").value = savedData.skills || ""; document.getElementById("highestDegree").value = savedData.highestDegree || ""; } }); Lastly, it is good practice to remove data from localStorage as soon as it is no longer needed: // Clear data on form submit form.addEventListener('submit', () => { // Clear localStorage once the form is submitted localStorage.removeItem('formData'); }); Adding The Current Step Value To localStorage If the user accidentally closes their browser, they should be able to return to wherever they left off. This means that the current step value also has to be saved in localStorage. To save this value, append the following line to the showStep() function: localStorage.setItem("storedStep", currentStep); Now we can retrieve the current step value and return users to wherever they left off whenever the DOM content loads. Add the following code to the DOMContentLoaded handler to do so: const storedStep = localStorage.getItem("storedStep"); if (storedStep) { const storedStepInt = parseInt(storedStep); steps.forEach((el, index) => { el.hidden = index + 1 !== storedStepInt; }); currentStep = storedStepInt; currentStepDiv.innerText = currentStep; } Also, do not forget to clear the current step value from localStorage when the form is submitted. localStorage.removeItem("storedStep"); The above line should be added to the submit handler. Wrapping Up Creating multi-step forms can help improve user experience for complex data entry. By carefully planning out steps, implementing form validation at each step, and temporarily storing user data in the browser, you make it easier for users to complete long forms. For the full implementation of this multi-step form, you can access the complete code on GitHub.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              Dreaming Of Miracles (December 2024 Wallpapers Edition)

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                December is almost here, and that means: It’s time for some new desktop wallpapers! Created with love by creatives from all around the world, they are bound to lighten up the last few weeks of the year and, who knows, maybe even spark new ideas. Enjoy!

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                As the year is coming to a close, many of us feel rushed, meeting deadlines, finishing off projects, or preparing for the upcoming holiday season. So how about some beautiful, wintery desktop wallpapers to sweeten up the month and get you in the mood for December — and the holidays, if you’re celebrating? More than thirteen years ago, we started our monthly wallpapers series here at Smashing Magazine. It’s the perfect opportunity to put your creative skills to the test but also to find just the right wallpaper to accompany you through the new month. This month is no exception, of course, so following our cozy little tradition, we have a new collection of December wallpapers for you to choose from. All of them were created with love by artists and designers from across the globe and can be downloaded for free. A huge thank you to everyone who tickled their creativity and shared their designs with us. This post wouldn’t exist without you. ❤️ Happy December! You can click on every image to see a larger preview. We respect and carefully consider the ideas and motivation behind each and every artist’s work. This is why we give all artists the full freedom to explore their creativity and express emotions and experience through their works. This is also why the themes of the wallpapers weren’t anyhow influenced by us but rather designed from scratch by the artists themselves. Submit your wallpaper design! 👩‍🎨 Feeling inspired? We are always looking for creative talent and would love to feature your desktop wallpaper in one of our upcoming posts. We can’t wait to see what you’ll come up with! Paws-itively Festive! “This holiday season, even our furry friends are getting in the spirit! Our mischievous little tree-topper has found the purr-fect perch to keep an eye on all the festivities. May your days be merry, bright, and filled with joyful surprises just like this one!” — Designed by PopArt Studio from Serbia. preview with calendar: 320x480, 640x480, 800x480, 800x600, 1024x768, 1024x1024, 1152x864, 1280x720, 1280x800, 1280x960, 1280x1024, 1400x1050, 1440x900, 1600x1200, 1680x1050, 1680x1200, 1920x1080, 1920x1200, 1920x1440, 2560x1440 without calendar: 320x480, 640x480, 800x480, 800x600, 1024x768, 1024x1024, 1152x864, 1280x720, 1280x800, 1280x960, 1280x1024, 1400x1050, 1440x900, 1600x1200, 1680x1050, 1680x1200, 1920x1080, 1920x1200, 1920x1440, 2560x1440 Merry Christmmm… Designed by Ricardo Gimenes from Spain. preview with calendar: 640x480, 800x480, 800x600, 1024x768, 1024x1024, 1152x864, 1280x720, 1280x800, 1280x960, 1280x1024, 1366x768, 1400x1050, 1440x900, 1600x1200, 1680x1050, 1680x1200, 1920x1080, 1920x1200, 1920x1440, 2560x1440, 3840x2160 without calendar: 640x480, 800x480, 800x600, 1024x768, 1024x1024, 1152x864, 1280x720, 1280x800, 1280x960, 1280x1024, 1366x768, 1400x1050, 1440x900, 1600x1200, 1680x1050, 1680x1200, 1920x1080, 1920x1200, 1920x1440, 2560x1440, 3840x2160 Dung Beetle Designed by Ricardo Gimenes from Spain. preview with calendar: 640x480, 800x480, 800x600, 1024x768, 1024x1024, 1152x864, 1280x720, 1280x800, 1280x960, 1280x1024, 1366x768, 1400x1050, 1440x900, 1600x1200, 1680x1050, 1680x1200, 1920x1080, 1920x1200, 1920x1440, 2560x1440, 3840x2160 without calendar: 640x480, 800x480, 800x600, 1024x768, 1024x1024, 1152x864, 1280x720, 1280x800, 1280x960, 1280x1024, 1366x768, 1400x1050, 1440x900, 1600x1200, 1680x1050, 1680x1200, 1920x1080, 1920x1200, 1920x1440, 2560x1440, 3840x2160 Dear Moon, Merry Christmas Designed by Vlad Gerasimov from Georgia. preview without calendar: 800x480, 800x600, 1024x600, 1024x768, 1152x864, 1280x720, 1280x800, 1280x960, 1280x1024, 1366x768, 1400x1050, 1440x900, 1440x960, 1600x900, 1600x1200, 1680x1050, 1680x1200, 1920x1080, 1920x1200, 1920x1440, 2560x1440, 2560x1600, 2880x1800, 3072x1920, 3840x2160, 5120x2880 Cardinals In Snowfall “During Christmas season, in the cold, colorless days of winter, Cardinal birds are seen as symbols of faith and warmth. In the part of America I live in, there is snowfall every December. While the snow is falling, I can see gorgeous Cardinals flying in and out of my patio. The intriguing color palette of the bright red of the Cardinals, the white of the flurries and the brown/black of dry twigs and fallen leaves on the snow-laden ground fascinates me a lot, and inspired me to create this quaint and sweet, hand-illustrated surface pattern design as I wait for the snowfall in my town!” — Designed by Gyaneshwari Dave from the United States. preview without calendar: 640x960, 768x1024, 1280x720, 1280x1024, 1366x768, 1920x1080, 2560x1440 The House On The River Drina “Since we often yearn for a peaceful and quiet place to work, we have found inspiration in the famous house on the River Drina in Bajina Bašta, Serbia. Wouldn’t it be great being in nature, away from civilization, swaying in the wind and listening to the waves of the river smashing your house, having no neighbors to bother you? Not sure about the Internet, though…” — Designed by PopArt Studio from Serbia. preview without calendar: 640x480, 800x600, 1024x1024, 1152x864, 1280x720, 1280x960, 1280x1024, 1366x768, 1400x1050, 1440x900, 1600x1200, 1680x1200, 1920x1080, 1920x1200, 1920x1440, 2560x1440 Enchanted Blizzard “A seemingly forgotten world under the shade of winter glaze hides a moment where architecture meets fashion and change encounters steadiness.” — Designed by Ana Masnikosa from Belgrade, Serbia. preview without calendar: 320x480, 640x480, 800x480, 800x600, 1024x768, 1024x1024, 1152x864, 1280x720, 1280x800, 1280x960, 1280x1024, 1400x1050, 1440x900, 1600x1200, 1680x1050, 1680x1200, 1920x1080, 1920x1200, 1920x1440, 2560x1440 Christmas Cookies “Christmas is coming and a great way to share our love is by baking cookies.” — Designed by Maria Keller from Mexico. preview without calendar: 320x480, 640x480, 640x1136, 750x1334, 800x480, 800x600, 1024x768, 1024x1024, 1152x864, 1242x2208, 1280x720, 1280x800, 1280x960, 1280x1024, 1366x768, 1400x1050, 1440x900, 1600x1200, 1680x1050, 1680x1200, 1920x1080, 1920x1200, 1920x1440, 2560x1440, 2880x1800 Sweet Snowy Tenderness “You know that warm feeling when you get to spend cold winter days in a snug, homey, relaxed atmosphere? Oh, yes, we love it, too! It is the sentiment we set our hearts on for the holiday season, and this sweet snowy tenderness is for all of us who adore watching the snowfall from our windows. Isn’t it romantic?” — Designed by PopArt Studio from Serbia. preview without calendar: 320x480, 640x480, 800x480, 800x600, 1024x768, 1024x1024, 1152x864, 1280x720, 1280x800, 1280x960, 1280x1024, 1366x768, 1400x1050, 1440x900, 1600x1200, 1680x1050, 1680x1200, 1920x1080, 1920x1200, 1920x1440, 2560x1440 Getting Hygge “There’s no more special time for a fire than in the winter. Cozy blankets, warm beverages, and good company can make all the difference when the sun goes down. We’re all looking forward to generating some hygge this winter, so snuggle up and make some memories.” — Designed by The Hannon Group from Washington D.C. preview without calendar: 320x480, 640x480, 800x600, 1024x768, 1280x960, 1440x900, 1600x1200, 1680x1050, 1680x1200, 1920x1080, 1920x1440, 2560x1440 Anonymoose Designed by Ricardo Gimenes from Spain. preview without calendar: 640x480, 800x480, 800x600, 1024x768, 1024x1024, 1152x864, 1280x720, 1280x800, 1280x960, 1280x1024, 1366x768, 1400x1050, 1440x900, 1600x1200, 1680x1050, 1680x1200, 1920x1080, 1920x1200, 1920x1440, 2560x1440, 3840x2160 Joy To The World “Joy to the world, all the boys and girls now, joy to the fishes in the deep blue sea, joy to you and me.” — Designed by Morgan Newnham from Boulder, Colorado. preview without calendar: 320x480, 640x480, 800x480, 800x600, 1024x768, 1024x1024, 1152x864, 1280x720, 1280x800, 1280x960, 1280x1024, 1400x1050, 1440x900, 1600x1200, 1680x1050, 1680x1200, 1920x1080, 1920x1200, 1920x1440, 2560x1440 King Of Pop Designed by Ricardo Gimenes from Spain. preview without calendar: 640x480, 800x480, 800x600, 1024x768, 1024x1024, 1152x864, 1280x720, 1280x800, 1280x960, 1280x1024, 1366x768, 1400x1050, 1440x900, 1600x1200, 1680x1050, 1680x1200, 1920x1080, 1920x1200, 1920x1440, 2560x1440, 3840x2160 Christmas Woodland Designed by Mel Armstrong from Australia. preview without calendar: 320x480, 640x480, 800x480, 800x600, 1024x768, 1024x1024, 1152x864, 1280x720, 1280x800, 1280x960, 1280x1024, 1366x768, 1400x1050, 1440x900, 1600x1200, 1680x1050, 1680x1200, 1920x1080, 1920x1200, 1920x1440, 2560x1440 Catch Your Perfect Snowflake “This time of year, people tend to dream big and expect miracles. Let your dreams come true!” Designed by Igor Izhik from Canada. preview without calendar: 800x480, 800x600, 1024x768, 1024x1024, 1152x864, 1280x720, 1280x800, 1280x960, 1280x1024, 1400x1050, 1440x900, 1600x1200, 1680x1050, 1680x1200, 1920x1080, 1920x1200, 1920x1440, 2560x1440, 2560x1600 Trailer Santa “A mid-century modern Christmas scene outside the norm of snowflakes and winter landscapes.” Designed by Houndstooth from the United States. preview without calendar: 1024x1024, 1280x800, 1280x1024, 1440x900, 1680x1050, 2560x1440 Silver Winter Designed by Violeta Dabija from Moldova. preview without calendar: 1024x768, 1280x800, 1440x900, 1680x1050, 1920x1200, 2560x1440 Gifts Lover Designed by Elise Vanoorbeek from Belgium. preview without calendar: 800x480, 800x600, 1024x768, 1024x1024, 1152x864, 1280x800, 1280x960, 1280x1024, 1366x768, 1400x1050, 1440x900, 1600x1200, 1680x1050, 1680x1200, 1920x1080, 1920x1200, 1920x1440, 2560x1440 On To The Next One “Endings intertwined with new beginnings, challenges we rose to and the ones we weren’t up to, dreams fulfilled and opportunities missed. The year we say goodbye to leaves a bitter-sweet taste, but we’re thankful for the lessons, friendships, and experiences it gave us. We look forward to seeing what the new year has in store, but, whatever comes, we will welcome it with a smile, vigor, and zeal.” — Designed by PopArt Studio from Serbia. preview without calendar: 320x480, 640x480, 800x480, 800x600, 1024x768, 1024x1024, 1152x864, 1280x720, 1280x800, 1280x960, 1280x1024, 1366x768, 1400x1050, 1440x900, 1600x1200, 1680x1050, 1680x1200, 1920x1080, 1920x1200, 1920x1440, 2560x1440 The Matterhorn “Christmas is always such a magical time of year so we created this wallpaper to blend the majestry of the mountains with a little bit of magic.” — Designed by Dominic Leonard from the United Kingdom. preview without calendar: 320x480, 800x600, 1024x768, 1280x720, 1400x1050, 1680x1200, 1920x1080, 1920x1200, 1920x1440, 2560x1440 Ninja Santa Designed by Elise Vanoorbeek from Belgium. preview without calendar: 1280x1024, 1366x768, 1400x1050, 1440x900, 1600x1200, 1680x1050, 1680x1200, 1920x1080, 1920x1440, 2560x1440 It’s In The Little Things Designed by Thaïs Lenglez from Belgium. preview without calendar: 640x480, 800x600, 1024x768, 1280x1024, 1440x900, 1600x1200, 1680x1050, 1920x1080, 1920x1200, 2560x1440 Ice Flowers “I took some photos during a very frosty and cold week before Christmas.” Designed by Anca Varsandan from Romania. preview without calendar: 1024x768, 1280x800, 1440x900, 1680x1050, 1920x1200 Surprise “Surprise is the greatest gift which life can grant us.” — Designed by PlusCharts from India. preview without calendar: 360x640, 1024x768, 1280x720, 1280x800, 1280x960, 1280x1024, 1366x768, 1400x1050, 1440x900, 1600x900, 1680x1200, 1920x1080 Season’s Greetings From Australia Designed by Tazi Designs from Australia. preview without calendar: 320x480, 640x480, 800x600, 1024x768, 1152x864, 1280x720, 1280x960, 1600x1200, 1920x1080, 1920x1440, 2560x1440 Christmas Selfie Designed by Emanuela Carta from Italy. preview without calendar: 320x480, 800x600, 1280x800, 1280x1024, 1440x900, 1680x1050, 2560x1440 Winter Wonderland “‘Winter is the time for comfort, for good food and warmth, for the touch of a friendly hand and for a talk beside the fire: it is the time for home.’ (Edith Sitwell) — Designed by Dipanjan Karmakar from India. preview without calendar: 1280x720, 1280x800, 1280x960, 1280x1024, 1366x768, 1400x1050, 1440x900, 1600x1200, 1680x1050, 1680x1200, 1920x1080, 1920x1440, 2560x1440 Winter Morning “Early walks in the fields when the owls still sit on the fences and stare funny at you.” — Designed by Bo Dockx from Belgium. preview without calendar: 320x480, 640x480, 800x480, 800x600, 1024x768, 1024x1024, 1152x864, 1280x720, 1280x800, 1280x960, 1280x1024, 1366x768, 1400x1050, 1440x900, 1600x1200, 1680x1050, 1920x1080, 1920x1200, 1920x1440, 2560x1440 Dream What You Want To Do “The year will end, hope the last month, you can do what you want to do, seize the time, cherish yourself, expect next year we will be better!” — Designed by Hong Zi-Qing from Taiwan. preview without calendar: 1024x768, 1152x864, 1280x720, 1280x960, 1366x768, 1400x1050, 1530x900, 1600x1200, 1920x1080, 1920x1440, 2560x1440 Happy Holidays Designed by Ricardo Gimenes from Spain. preview without calendar: 640x480, 800x480, 800x600, 1024x768, 1024x1024, 1152x864, 1280x720, 1280x800, 1280x960, 1280x1024, 1366x768, 1400x1050, 1440x900, 1600x1200, 1680x1050, 1680x1200, 1920x1080, 1920x1200, 1920x1440, 2560x1440, 3840x2160

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                The Hype Around Signals

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  From KnockoutJS to modern UI libraries like SolidJS, Vue.js, and Svelte, signals revolutionized how we think about reactivity in UIs. Here’s a deep dive into their history and impact by Atila Fassina.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  The groundwork for what we call today “signals” dates as early as the 1970s. Based on this work, they became popular with different fields of computer science, defining them more specifically around the 90s and the early 2000s. In Web Development, they first made a run for it with KnockoutJS, and shortly after, signals took a backseat in (most of) our brains. Some years ago, multiple similar implementations came to be. MobX observable states Vue.js refs and shallow refs SolidJS signals With different names and implementation details, those approaches are similar enough to be wrapped in a category we know today as Fine-Grained Reactivity, even if they have different levels of “fine” x “coarse” updates — we’ll get more into what this means soon enough. To summarize the history: Even being an older technology, signals started a revolution in how we thought about interactivity and data in our UIs at the time. And since then, every UI library (SolidJS, Marko, Vue.js, Qwik, Angular, Svelte, Wiz, Preact, etc) has adopted some kind of implementation of them (except for React). Typically, a signal is composed of an accessor (getter) and a setter. The setter establishes an update to the value held by the signal and triggers all dependent effects. While an accessor pulls the value from the source and is run by effects every time a change happens upstream. const [signal, setSignal] = createSignal("initial value"); setSignal("new value"); console.log(signal()); // "new value" In order to understand the reason for that, we need to dig a little deeper into what API Architectures and Fine-Grained Reactivity actually mean. API Architectures There are two basic ways of defining systems based on how they handle their data. Each of these approaches has its pros and cons. Pull: The consumer pings the source for updates. Push: The source sends the updates as soon as they are available. Pull systems need to handle polling or some other way of maintaining their data up-to-date. They also need to guarantee that all consumers of the data get torn down and recreated once new data arrives to avoid state tearing. State Tearing occurs when different parts of the same UI are at different stages of the state. For example, when your header shows 8 posts available, but the list has 10. Push systems don’t need to worry about maintaining their data up-to-date. Nevertheless, the source is unaware of whether the consumer is ready to receive the updates. This can cause backpressure. A data source may send too many updates in a shorter amount of time than the consumer is capable of handling. If the update flux is too intense for the receiver, it can cause loss of data packages (leading to state tearing once again) and, in more serious cases, even crash the client. In pull systems, the accepted tradeoff is that data is unaware of where it’s being used; this causes the receiving end to create precautions around maintaining all their components up-to-date. That’s how systems like React work with their teardown/re-render mechanism around updates and reconciliation. In push systems, the accepted tradeoff is that the receiving end needs to be able to deal with the update stream in a way that won’t cause it to crash while maintaining all consuming nodes in a synchronized state. In web development, RxJS is the most popular example of a push system. The attentive reader may have noticed the tradeoffs on each system are at the opposite ends of the spectrum: while pull systems are good at scheduling the updates efficiently, in push architectures, the data knows where it’s being used — allows for more granular control. That’s what makes a great opportunity for a hybrid model. Push-Pull Architectures In Push-Pull systems, the state has a list of subscribers, which can then trigger for re-fetching data once there is an update. The way it differs from traditional push is that the update itself isn’t sent to the subscribers — just a notification that they’re now stale. Once the subscriber is aware its current state has become stale, it will then fetch the new data at a proper time, avoiding any kind of backpressure and behaving similarly to the pull mechanism. The difference is that this only happens when the subscriber is certain there is new data to be fetched. We call these data signals, and the way those subscribers are triggered to update are called effects. Not to confuse with useEffect, which is a similar name for a completely different thing. Fine-Grained Reactivity Once we establish the two-way interaction between the data source and data consumer, we will have a reactive system. A reactive system only exists when data can notify the consumer it has changed, and the consumer can apply those changes. Now, to make it fine-grained there are two fundamental requirements that need to be met: Efficiency: The system only executes the minimum amount of computations necessary. Glitch-Free: No intermediary states are shown in the process of updating a state. Efficiency In UIs To really understand how signals can achieve high levels of efficiency, one needs to understand what it means to have an accessor. In broad strokes, they behave as getter functions. Having an accessor means the value does not exist within the boundaries of our component — what our templates receive is a getter for that value, and every time their effects run, they will bring an up-to-date new value. This is why signals are functions and not simple variables. For example, in Solid: import { createSignal } from 'solid-js' function ReactiveComponent() { const [signal, setSignal] = createSignal() return ( <h1>Hello, {signal()}</h1> ) } The part that is relevant to performance (and efficiency) in the snippet above is that considering signal() is a getter, it does not need to re-run the whole ReactiveComponent() function to update the rendered artifact; only the signal is re-run, guaranteeing no extra computation will run. Glitch-Free UIs Non-reactive systems avoid intermediary states by having a teardown/re-render mechanism. They toss away the artifacts with possibly stale data and recreate everything from scratch. That works well and consistently but at the expense of efficiency. In order to understand how reactive systems handle this problem, we need to talk about the Diamond Challenge. This is a quick problem to describe but a tough one to solve. Take a look at the diagram below: Pay attention to the E node. It depends on D and B, but only D depends on C. If your reactive system is too eager to update, it can receive the update from B while D is still stale. That will cause E to show an intermediary state that should not exist. It’s easy and intuitive to have A trigger its children for updates as soon as new data arrives and let it cascade down. But if this happens, E receives the data from B while D is stale. If B is able to trigger an update from E, E will show an intermediate state. Each implementation adopts different update strategies to solve this challenge. They can be grouped into two categories: Lazy Signals Where a scheduler defines the order within which the updates will occur. (A, then B and C, then D, and finally E). Eager Signals When signals are aware if their parents are stale, checking, or clean. In this approach, when E receives the update from B, it will trigger a check/update on D, which will climb up until it can ensure to be back in a clean state, allowing E to finally update. Back To Our UIs After this dive into what fine-grained reactivity means, it’s time to take a step back and look at our websites and apps. Let’s analyze what it means to our daily work. DX And UX When the code we wrote is easier to reason about, we can then focus on the things that really matter: the features we deliver to our users. Naturally, tools that require less work to operate will deliver less maintenance and overhead for the craftsperson. A system that is glitch-free and efficient by default will get out of the developer’s way when it’s time to build with it. It will also enforce a higher connection to the platform via a thinner abstraction layer. When it comes to Developer Experience, there is also something to be said about known territory. People are more productive within the mental models and paradigms they are used to. Naturally, solutions that have been around for longer and have solved a larger quantity of challenges are easier to work with, but that is at odds with innovation. It was a cognitive exercise when JSX came around and replaced imperative DOM updates with jQuery. In the same way, a new paradigm to handle rendering will cause a similar discomfort until it becomes common. Going Deeper We will talk further about this in the next article, where we’re looking more closely into different implementations of signals (lazy, eager, hybrid), scheduled updates, interacting with the DOM, and debugging your own code! Meanwhile, you can find me in the comments section below, on 𝕏 (Twitter), LinkedIn, BlueSky, or even youtube. I’m always happy to chat, and if you tell me what you want to know, I’ll make sure to include it in the next article! See ya!