# Starting a new project

A complete `.install4j` project is hundreds of lines of XML with dozens of internal `id` cross-references and many container elements whose required children are not obvious from the schema alone. **Do not write one from scratch.** Copy a known-good project, then rename and trim.

## Pick a starting point

| Starting point | When to use it |
|---|---|
| `samples/hello/hello.install4j` | Typical app: three launchers (CLI, Swing GUI, Windows service), full auto-update chain, JPMS module, Ant + Maven + Gradle build hooks. The closest thing to a "default modern install4j project". |
| `samples/customCode/customCode.install4j` | When the project will register `<beanClass>` extensions (custom screen / action / form component / style / L&F handler). Includes the `<customCode>` block and the corresponding Java sources. |
| `samples/properties/properties.install4j` | When the installer must read, edit, and write a `.properties` file across the install flow. |
| `samples/formScreen/jdkSelection.install4j` | XML-only; advanced form screen with `<validation>` / `<preActivation>` / `<initScript>` lifecycle scripts and a JDK selection flow. |
| `samples/mergedProjects/mergedProjects.install4j` | Multi-project / multi-product layouts using `<mergedProjects>` and `<link>`. |

`samples/README.md` indexes the same projects with the specific files and patterns inside each one.

## Pre-built installer-application blocks

`assets/application-templates.install4j` contains three canonical installer applications you can drop into a project's `<installerGui><applications>` block:

- **Standalone update downloader** (id `1`) — user-driven "Check for update" entry point.
- **Blocking update downloader** (id `3`) — runs at launcher startup, blocks until the check completes.
- **Background update downloader** (id `452`) — runs asynchronously at startup; pairs with `UpdateChecker.executeScheduledUpdate` (see `samples/hello`).

Copy the entire `<application id="…">…</application>` block, then renumber every `id` to fit the target project (see *IDs* below). The file itself is an install4j project with `applicationTemplates="true"` on the root — that attribute should NOT be present in a real project.

## Adapting a starting point

After copying, the typical changes are:

1. **`<application name= version= shortName= applicationId=>`** — set to your product. `applicationId` must be unique per product (used by the runtime to scope preferences and uninstall keys).
2. **Compiler variables under `<application><variables>`** — replace the sample's variables with yours (`appName`, `mainClass`, etc.).
3. **`<launchers>`** — rename the launcher(s); update `mainClass`, executable name, icon files.
4. **`<files>` `<roots>` / `<entries>`** — point at your distribution tree.
5. **`<mediaSets>`** — keep only the media for your target platforms.
6. **Renumber every `id`** in any block you copy in from `assets/application-templates.install4j` or from another project — see below.

## IDs

- `id` is a string attribute (in the schema) that holds integer values by convention; it appears on most container elements (`mountPoint`, `launcher`, `screen`, `action`, `formComponent`, `application`, `mediaSet`, `style`, `link`, `group`, …).
- IDs are referenced from elsewhere in the file: `<fileEntry mountPoint="…">`, `<launcherIds><launcher id="…"/></launcherIds>`, `styleId="…"` on screens, `targetId` / `mergedProjectId` on `<link>`, `coupledComponentIds` mutations, etc.
- When merging two starting points (e.g. dropping an updater template into the hello sample), every imported `id` must be renumbered to `max(existing) + 1, +2, …` AND every reference to those IDs must be updated to match.
- For installer/uninstaller applications inside `<installerGui><applications>`, the conventional IDs are the literal strings `installer` and `uninstaller`, not integers.

## Top-level shape (reference only — do not copy verbatim)

For understanding what every direct child of `<install4j>` is, this is the schema-defined skeleton. The starting points above are valid instances of it; this XML is *not*.

The root element carries `version` and, on tooling-written files, `transformSequenceNumber`. Set `version` to the install4j build that owns the file (`13.0` for this skill bundle). **Do not set `transformSequenceNumber` on a new project** — when absent, install4j treats the file as already current and skips all schema-migration transforms; install4jc / the IDE fills it in the next time they save. 

```xml
<?xml version="1.0" encoding="UTF-8"?>
<install4j version="13.0">

  <!-- Project-level settings: name, applicationId, JRE search sequence,
       compiler variables, code signing, merged-project links, project-wide
       JRE bundle. Schema type: Install4JApplicationConfigType. -->
  <application name="…" version="…" shortName="…" applicationId="…">
    <languages>…</languages>
    <searchSequence>…</searchSequence>
    <variables>…</variables>
    <mergedProjects/>
    <codeSigning .../>
    <jreBundles .../>
  </application>

  <!-- Files to install. → doc/concepts/files.md
       Schema type: FilesConfigType. -->
  <files>
    <filesets/>
    <roots/>
    <mountPoints>…</mountPoints>
    <entries>…</entries>
    <components/>
  </files>

  <!-- Application launchers. → doc/concepts/launchers.md
       Schema type: LaunchersConfigType. Each <launcher> is verbose
       (executable, java, classPath, vmOptionsFile, customScript,
       infoPlist, iconImageFiles all required even if empty). -->
  <launchers>
    <launcher name="…" id="…">…</launcher>
  </launchers>

  <!-- Installer GUI: applications (installer + uninstaller flow), screen styles,
       widget styles. → doc/concepts/screensAndActions.md
       Schema type: InstallerGuiConfigType.
       installerType is "regular" (default, omit) or "addon" for an add-on installer. -->
  <installerGui>
    <applications>
      <application id="installer"
                   beanClass="com.install4j.runtime.beans.applications.InstallerApplication">
        <serializedBean/>
        <screens>
          <!-- screens go here. See reference/beans/screens.md for available classes
               and reference/serialized-bean-format.md for the property encoding. -->
        </screens>
      </application>
      <application id="uninstaller"
                   beanClass="com.install4j.runtime.beans.applications.UninstallerApplication"/>
    </applications>
    <styles defaultStyleId="…">…</styles>
    <widgetStyles defaultWidgetStyleId="…">…</widgetStyles>
  </installerGui>

  <!-- Per-platform output artefacts. → doc/concepts/mediaFiles.md
       Schema type: MediaSetsConfigType. Each child element name (windows /
       unixInstaller / macos / unixArchive / etc.) selects the media format. -->
  <mediaSets>…</mediaSets>

</install4j>
```

Every direct child of `<install4j>` is technically optional in the schema, but a project with no `<application>`, `<launchers>`, or `<mediaSets>` won't produce any output. The default screen/style/widget-style content, the JVM search sequence, and sensible mediaSet defaults are generated by the install4j IDE from its own templates and Java code — not reproducible by hand.
