[Here's a paper](https://www.researchgate.net/publication/313587388_Kinematic_and_dynamic_modelling_of_UR5_manipulator) that includes the derivation of analytical IK solutions for the UR5, but says that the wrist is not spherical.

There's also an implementation of analytical IK [here](https://github.com/ros-industrial/universal_robot/blob/melodic-devel/ur_kinematics/src/ur_kin.cpp) in the [`ur_kinematics` package](https://github.com/ros-industrial/universal_robot/tree/melodic-devel/ur_kinematics) for ROS 1. There may be a limitation that these IK solutions only work with the nominal kinematic structure of the robot.

The UR robots store an internal factory calibration that describes the as-manufactured kinematics of the physical robot. This can be important for accurate IK solutions. See, for example the [ROS 2 package `ur_calibration`](https://github.com/UniversalRobots/Universal_Robots_ROS2_Driver/tree/main/ur_calibration).

I don't know if using the calibrated kinematics breaks some assumptions in the solution process or not. (For example, no real-world as-built robot has strictly parallel axes for the shoulder lift, elbow, and first wrist joint.) 

I agree with other answers that I'd use an existing IK package. I've personally found that numerical inverse kinematics solutions are fast enough for anything I've done with UR arms. 

If you do need closed-form solutions, you can take a look at the [IKFast library](http://openrave.org/docs/latest_stable/openravepy/ikfast/#ikfast-compiler). I also came across [this library](https://github.com/cambel/ur_ikfast/
) which uses IKFast to find solutions for the UR arms. It looks like the `ur_kinematics` ROS 1 package can also use an IKFast solution if it's available.