In this tutorial, you will learn the basics of Dagger by building a Dagger project from scratch. This simple project deploys a [React](https://reactjs.org/) application to your local machine via Docker. In later tutorials, you will learn how to configure Dagger to deploy to remote infrastructure such as EKS and GKE.
- The `cue.mod` directory stores libraries such as [dagger/universe](https://github.com/dagger/universe) which can be _imported_ into your Dagger plan.
A Dagger _plan_ is written in CUE and defines the _resources_, _dependencies_, and _logic_ to deploy an application to an environment. Unlike traditional glue code written in a scripting language such as Bash or PowerShell, a Dagger plan is _declarative_ rather than _imperative_. This frees us from thinking about the order of operations, since Dagger will infer dependencies and calculate correct order on its own.
This file will define the resources and relationships between them that are common across _all environments_. For example, here we are deploying to our local Docker engine in our `local` environment, but for staging or production as examples, we would deploy the same image to some other container orchestration system such as Kubernetes hosted somewhere out there among the various cloud providers.
Notice that both files have the same `package todoapp` declared on the first line. This is crucial to inform CUE that they are to be loaded and evaluated together in the same context.
Our `local.cue` file now holds resources specific to our `local` environment. Also notice that we are defining a concrete value for the `target` key here. The entire `push` object is defined in both files and CUE will merge the values into a single struct with key:value pairs that are _complete_ with concrete values.
Before we can deploy the plan, we need to define an environment which is the specific plan to execute, as well as the context from which inputs are pulled and to which state is stored.
Our Dagger plan includes a number of references to `dagger.#Input` which inform the Dagger engine that the concrete value should be pulled from inputs at runtime. While some values such as the registry target we saw above can be expressed purely in CUE, others such as directories, secrets, and sockets are required to be explicitly defined as _inputs_ to protect against malicious code being injected by third-party packages. If Dagger allowed such things to be stated in CUE, the entire package system could become a source of attacks.