def _run(
    env: constants.Env = constants.Env.DEV,
    frontend: bool = True,
    backend: bool = True,
    frontend_port: int | None = None,
    backend_port: int | None = None,
    backend_host: str | None = None,
):
    """Run the app in the given directory."""
    from reflex.utils import build, exec, prerequisites, processes

    config = get_config()

    backend_host = backend_host or config.backend_host

    # Set env mode in the environment
    environment.REFLEX_ENV_MODE.set(env)

    # Show system info
    exec.output_system_info()

    # If no --frontend-only and no --backend-only, then turn on frontend and backend both
    frontend, backend = prerequisites.check_running_mode(frontend, backend)
    if not frontend and backend:
        _skip_compile()

    prerequisites.assert_in_reflex_dir()

    # Check that the app is initialized.
    if frontend and prerequisites.needs_reinit():
        _init(name=config.app_name)

    # Delete the states folder if it exists.
    reset_disk_state_manager()

    # Find the next available open port if applicable.
    if frontend:
        auto_increment_frontend = not bool(frontend_port or config.frontend_port)
        frontend_port = processes.handle_port(
            "frontend",
            (
                frontend_port
                or config.frontend_port
                or constants.DefaultPorts.FRONTEND_PORT
            ),
            auto_increment=auto_increment_frontend,
        )

    if backend:
        auto_increment_backend = not bool(backend_port or config.backend_port)

        backend_port = processes.handle_port(
            "backend",
            (
                backend_port
                or config.backend_port
                or constants.DefaultPorts.BACKEND_PORT
            ),
            auto_increment=auto_increment_backend,
        )

    # Apply the new ports to the config.
    if frontend_port != config.frontend_port:
        config._set_persistent(frontend_port=frontend_port)
    if backend_port != config.backend_port:
        config._set_persistent(backend_port=backend_port)

    # Reload the config to make sure the env vars are persistent.
    get_config(reload=True)

    console.rule("[bold]Starting Reflex App")

    prerequisites.check_latest_package_version(constants.Reflex.MODULE_NAME)

    # Get the app module.
    app_task = prerequisites.compile_or_validate_app
    args = (frontend,)
    kwargs = {
        "check_if_schema_up_to_date": True,
    }

    # Granian fails if the app is already imported.
    if should_use_granian():
        import concurrent.futures

        compile_future = concurrent.futures.ProcessPoolExecutor(max_workers=1).submit(
            app_task,
            *args,
            **kwargs,
        )
        validation_result = compile_future.result()
    else:
        validation_result = app_task(*args, **kwargs)

    if not validation_result:
        raise click.exceptions.Exit(1)

    # Get the frontend and backend commands, based on the environment.
    setup_frontend = frontend_cmd = backend_cmd = None
    if env == constants.Env.DEV:
        setup_frontend, frontend_cmd, backend_cmd = (
            build.setup_frontend,
            exec.run_frontend,
            exec.run_backend,
        )
    if env == constants.Env.PROD:
        setup_frontend, frontend_cmd, backend_cmd = (
            build.setup_frontend_prod,
            exec.run_frontend_prod,
            exec.run_backend_prod,
        )
    if not setup_frontend or not frontend_cmd or not backend_cmd:
        msg = f"Invalid env: {env}. Must be DEV or PROD."
        raise ValueError(msg)

    # Post a telemetry event.
    telemetry.send(f"run-{env.value}")

    # Display custom message when there is a keyboard interrupt.
    atexit.register(processes.atexit_handler)

    # Run the frontend and backend together.
    commands = []

    # Run the frontend on a separate thread.
    if frontend:
        setup_frontend(Path.cwd())
        commands.append((frontend_cmd, Path.cwd(), frontend_port, backend))

    # In prod mode, run the backend on a separate thread.
    if backend and env == constants.Env.PROD:
        commands.append(
            (
                backend_cmd,
                backend_host,
                backend_port,
                config.loglevel.subprocess_level(),
                frontend,
            )
        )

    # Start the frontend and backend.
    with processes.run_concurrently_context(*commands):
        # In dev mode, run the backend on the main thread.
        if backend and backend_port and env == constants.Env.DEV:
            backend_cmd(
                backend_host,
                int(backend_port),
                config.loglevel.subprocess_level(),
                frontend,
            )
            # The windows uvicorn bug workaround
            # https://github.com/reflex-dev/reflex/issues/2335
            if constants.IS_WINDOWS and exec.frontend_process:
                # Sends SIGTERM in windows
                exec.kill(exec.frontend_process.pid)
Run the app in the given directory.
reflex/reflex.py